<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>SDL2_gfx: I:/Sources/sdl2gfx/SDL2_imageFilter.c Source File</title>

<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />



</head>
<body>
<div id="top"><!-- do not remove this div! -->


<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  
  
  <td style="padding-left: 0.5em;">
   <div id="projectname">SDL2_gfx
   &#160;<span id="projectnumber">1.0.1</span>
   </div>
   <div id="projectbrief">GraphicsprimitivesandsurfacefunctionsforSDL2</div>
  </td>
  
  
  
 </tr>
 </tbody>
</table>
</div>

<!-- Generated by Doxygen 1.8.0 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
  <div id="navrow2" class="tabs2">
    <ul class="tablist">
      <li><a href="files.html"><span>File&#160;List</span></a></li>
      <li><a href="globals.html"><span>Globals</span></a></li>
    </ul>
  </div>
</div>
<div class="header">
  <div class="headertitle">
<div class="title">I:/Sources/sdl2gfx/SDL2_imageFilter.c</div>  </div>
</div><!--header-->
<div class="contents">
<a href="_s_d_l2__image_filter_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
<a name="l00002"></a>00002 <span class="comment"></span>
<a name="l00003"></a>00003 <span class="comment">SDL2_imageFilter.c: byte-image &quot;filter&quot; routines</span>
<a name="l00004"></a>00004 <span class="comment"></span>
<a name="l00005"></a>00005 <span class="comment">Copyright (C) 2001-2012  Andreas Schiffler</span>
<a name="l00006"></a>00006 <span class="comment">Copyright (C) 2013  Sylvain Beucler</span>
<a name="l00007"></a>00007 <span class="comment"></span>
<a name="l00008"></a>00008 <span class="comment">This software is provided &#39;as-is&#39;, without any express or implied</span>
<a name="l00009"></a>00009 <span class="comment">warranty. In no event will the authors be held liable for any damages</span>
<a name="l00010"></a>00010 <span class="comment">arising from the use of this software.</span>
<a name="l00011"></a>00011 <span class="comment"></span>
<a name="l00012"></a>00012 <span class="comment">Permission is granted to anyone to use this software for any purpose,</span>
<a name="l00013"></a>00013 <span class="comment">including commercial applications, and to alter it and redistribute it</span>
<a name="l00014"></a>00014 <span class="comment">freely, subject to the following restrictions:</span>
<a name="l00015"></a>00015 <span class="comment"></span>
<a name="l00016"></a>00016 <span class="comment">   1. The origin of this software must not be misrepresented; you must not</span>
<a name="l00017"></a>00017 <span class="comment">   claim that you wrote the original software. If you use this software</span>
<a name="l00018"></a>00018 <span class="comment">   in a product, an acknowledgment in the product documentation would be</span>
<a name="l00019"></a>00019 <span class="comment">   appreciated but is not required.</span>
<a name="l00020"></a>00020 <span class="comment"></span>
<a name="l00021"></a>00021 <span class="comment">   2. Altered source versions must be plainly marked as such, and must not be</span>
<a name="l00022"></a>00022 <span class="comment">   misrepresented as being the original software.</span>
<a name="l00023"></a>00023 <span class="comment"></span>
<a name="l00024"></a>00024 <span class="comment">   3. This notice may not be removed or altered from any source</span>
<a name="l00025"></a>00025 <span class="comment">   distribution.</span>
<a name="l00026"></a>00026 <span class="comment"></span>
<a name="l00027"></a>00027 <span class="comment">Andreas Schiffler -- aschiffler at ferzkopp dot net</span>
<a name="l00028"></a>00028 <span class="comment"></span>
<a name="l00029"></a>00029 <span class="comment">*/</span>
<a name="l00030"></a>00030 
<a name="l00031"></a>00031 <span class="comment">/*</span>
<a name="l00032"></a>00032 <span class="comment"></span>
<a name="l00033"></a>00033 <span class="comment">Note: Uses inline x86 MMX or ASM optimizations if available and enabled.</span>
<a name="l00034"></a>00034 <span class="comment"></span>
<a name="l00035"></a>00035 <span class="comment">Note: Most of the MMX code is based on published routines </span>
<a name="l00036"></a>00036 <span class="comment">by Vladimir Kravtchenko at vk@cs.ubc.ca - credits go to </span>
<a name="l00037"></a>00037 <span class="comment">him for his work.</span>
<a name="l00038"></a>00038 <span class="comment"></span>
<a name="l00039"></a>00039 <span class="comment">*/</span>
<a name="l00040"></a>00040 
<a name="l00041"></a>00041 <span class="preprocessor">#include &lt;stdio.h&gt;</span>
<a name="l00042"></a>00042 <span class="preprocessor">#include &lt;stdlib.h&gt;</span>
<a name="l00043"></a>00043 <span class="preprocessor">#include &lt;string.h&gt;</span>
<a name="l00044"></a>00044 
<a name="l00045"></a>00045 <span class="preprocessor">#include &quot;SDL.h&quot;</span>
<a name="l00046"></a>00046 
<a name="l00047"></a>00047 <span class="comment">/* Use GCC intrinsics if available: they support both i386 and x86_64,</span>
<a name="l00048"></a>00048 <span class="comment">   provide ASM-grade performances, and lift the PUSHA/POPA issues. */</span>
<a name="l00049"></a>00049 <span class="preprocessor">#ifdef __GNUC__</span>
<a name="l00050"></a>00050 <span class="preprocessor"></span><span class="preprocessor">#  ifdef USE_MMX</span>
<a name="l00051"></a>00051 <span class="preprocessor"></span><span class="preprocessor">#    include &lt;mmintrin.h&gt;</span>
<a name="l00052"></a>00052 <span class="preprocessor">#  endif</span>
<a name="l00053"></a>00053 <span class="preprocessor"></span><span class="preprocessor">#  include &lt;SDL_cpuinfo.h&gt;</span>
<a name="l00054"></a>00054 <span class="preprocessor">#endif</span>
<a name="l00055"></a>00055 <span class="preprocessor"></span>
<a name="l00056"></a>00056 <span class="preprocessor">#include &quot;<a class="code" href="_s_d_l2__image_filter_8h.html">SDL2_imageFilter.h</a>&quot;</span>
<a name="l00057"></a>00057 
<a name="l00061"></a><a class="code" href="_s_d_l2__image_filter_8c.html#a700fb30611761c46a674a45cc28ff561">00061</a> <span class="preprocessor">#define SWAP_32(x) (((x) &gt;&gt; 24) | (((x) &amp; 0x00ff0000) &gt;&gt; 8)  | (((x) &amp; 0x0000ff00) &lt;&lt; 8)  | ((x) &lt;&lt; 24))</span>
<a name="l00062"></a>00062 <span class="preprocessor"></span>
<a name="l00063"></a>00063 <span class="comment">/* ------ Static variables ----- */</span>
<a name="l00064"></a>00064 
<a name="l00068"></a>00068 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterUseMMX = 1;
<a name="l00069"></a>00069 
<a name="l00070"></a>00070 <span class="comment">/* Detect GCC */</span>
<a name="l00071"></a>00071 <span class="preprocessor">#if defined(__GNUC__)</span>
<a name="l00072"></a>00072 <span class="preprocessor"></span><span class="preprocessor">#define GCC__</span>
<a name="l00073"></a>00073 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l00074"></a>00074 <span class="preprocessor"></span>
<a name="l00080"></a><a class="code" href="_s_d_l2__image_filter_8h.html#ae3f67cbe712f604b16b6de3f4bfbf31c">00080</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>(<span class="keywordtype">void</span>)
<a name="l00081"></a>00081 {
<a name="l00082"></a>00082         <span class="comment">/* Check override flag */</span>
<a name="l00083"></a>00083         <span class="keywordflow">if</span> (SDL_imageFilterUseMMX == 0) {
<a name="l00084"></a>00084                 <span class="keywordflow">return</span> (0);
<a name="l00085"></a>00085         }
<a name="l00086"></a>00086 
<a name="l00087"></a>00087     <span class="keywordflow">return</span> SDL_HasMMX();
<a name="l00088"></a>00088 }
<a name="l00089"></a>00089 
<a name="l00093"></a><a class="code" href="_s_d_l2__image_filter_8h.html#afc46d09d46b1302becfc170214dee0c0">00093</a> <span class="keywordtype">void</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a5dff661660755161bb4aaf6199cd1384" title="Disable MMX check for filter functions and and force to use non-MMX C based code.">SDL_imageFilterMMXoff</a>()
<a name="l00094"></a>00094 {
<a name="l00095"></a>00095         SDL_imageFilterUseMMX = 0;
<a name="l00096"></a>00096 }
<a name="l00097"></a>00097 
<a name="l00101"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a0b1d8468dc6e6304b62276acbb7336f6">00101</a> <span class="keywordtype">void</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a353ee234c3b51b33c4c5c4b30db5832d" title="Enable MMX check for filter functions and use MMX code if available.">SDL_imageFilterMMXon</a>()
<a name="l00102"></a>00102 {
<a name="l00103"></a>00103         SDL_imageFilterUseMMX = 1;
<a name="l00104"></a>00104 }
<a name="l00105"></a>00105 
<a name="l00106"></a>00106 <span class="comment">/* ------------------------------------------------------------------------------------ */</span>
<a name="l00107"></a>00107 
<a name="l00118"></a>00118 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterAddMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength)
<a name="l00119"></a>00119 {
<a name="l00120"></a>00120 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l00121"></a>00121 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l00122"></a>00122 <span class="preprocessor"></span>        __asm
<a name="l00123"></a>00123         {
<a name="l00124"></a>00124                 pusha
<a name="l00125"></a>00125                         mov eax, Src1   <span class="comment">/* load Src1 address into eax */</span>
<a name="l00126"></a>00126                         mov ebx, Src2   <span class="comment">/* load Src2 address into ebx */</span>
<a name="l00127"></a>00127                         mov edi, Dest   <span class="comment">/* load Dest address into edi */</span>
<a name="l00128"></a>00128                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l00129"></a>00129                         shr ecx, 3      <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l00130"></a>00130                         align 16        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l00131"></a>00131 L1010:
<a name="l00132"></a>00132                 movq mm1, [eax] <span class="comment">/* load 8 bytes from Src1 into mm1 */</span>
<a name="l00133"></a>00133                 paddusb mm1, [ebx]      <span class="comment">/* mm1=Src1+Src2 (add 8 bytes with saturation) */</span>
<a name="l00134"></a>00134                 movq [edi], mm1 <span class="comment">/* store result in Dest */</span>
<a name="l00135"></a>00135                         add eax, 8      <span class="comment">/* increase Src1, Src2 and Dest  */</span>
<a name="l00136"></a>00136                         add ebx, 8      <span class="comment">/* register pointers by 8 */</span>
<a name="l00137"></a>00137                         add edi, 8
<a name="l00138"></a>00138                         dec ecx <span class="comment">/* decrease loop counter */</span>
<a name="l00139"></a>00139                         jnz L1010       <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l00140"></a>00140                         emms <span class="comment">/* exit MMX state */</span>
<a name="l00141"></a>00141                         popa
<a name="l00142"></a>00142         }
<a name="l00143"></a>00143 <span class="preprocessor">#else</span>
<a name="l00144"></a>00144 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l00145"></a>00145         __m64 *mSrc1 = (__m64*)Src1;
<a name="l00146"></a>00146         __m64 *mSrc2 = (__m64*)Src2;
<a name="l00147"></a>00147         __m64 *mDest = (__m64*)Dest;
<a name="l00148"></a>00148         <span class="keywordtype">int</span> i;
<a name="l00149"></a>00149         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l00150"></a>00150                 *mDest = _m_paddusb(*mSrc1, *mSrc2);    <span class="comment">/* Src1+Src2 (add 8 bytes with saturation) */</span>
<a name="l00151"></a>00151                 mSrc1++;
<a name="l00152"></a>00152                 mSrc2++;
<a name="l00153"></a>00153                 mDest++;
<a name="l00154"></a>00154         }
<a name="l00155"></a>00155         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l00156"></a>00156 <span class="preprocessor">#endif</span>
<a name="l00157"></a>00157 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l00158"></a>00158 <span class="preprocessor">#else</span>
<a name="l00159"></a>00159 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l00160"></a>00160 <span class="preprocessor">#endif</span>
<a name="l00161"></a>00161 <span class="preprocessor"></span>}
<a name="l00162"></a>00162 
<a name="l00173"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a1e4de9be8feb43595719fd0494601952">00173</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a9f06507eb0b63198dbd67495d61c9b20" title="Filter using Add: D = saturation255(S1 + S2)">SDL_imageFilterAdd</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
<a name="l00174"></a>00174 {
<a name="l00175"></a>00175         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l00176"></a>00176         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *cursrc2, *curdst;
<a name="l00177"></a>00177         <span class="keywordtype">int</span> result;
<a name="l00178"></a>00178 
<a name="l00179"></a>00179         <span class="comment">/* Validate input parameters */</span>
<a name="l00180"></a>00180         <span class="keywordflow">if</span> ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL))
<a name="l00181"></a>00181                 <span class="keywordflow">return</span>(-1);
<a name="l00182"></a>00182         <span class="keywordflow">if</span> (length == 0)
<a name="l00183"></a>00183                 <span class="keywordflow">return</span>(0);
<a name="l00184"></a>00184 
<a name="l00185"></a>00185         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l00186"></a>00186 
<a name="l00187"></a>00187                 <span class="comment">/* Use MMX assembly routine */</span>
<a name="l00188"></a>00188                 SDL_imageFilterAddMMX(Src1, Src2, Dest, length);
<a name="l00189"></a>00189 
<a name="l00190"></a>00190                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l00191"></a>00191                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l00192"></a>00192                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l00193"></a>00193                         istart = length &amp; 0xfffffff8;
<a name="l00194"></a>00194                         cursrc1 = &amp;Src1[istart];
<a name="l00195"></a>00195                         cursrc2 = &amp;Src2[istart];
<a name="l00196"></a>00196                         curdst = &amp;Dest[istart];
<a name="l00197"></a>00197                 } <span class="keywordflow">else</span> {
<a name="l00198"></a>00198                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l00199"></a>00199                         <span class="keywordflow">return</span> (0);
<a name="l00200"></a>00200                 }
<a name="l00201"></a>00201         } <span class="keywordflow">else</span> {
<a name="l00202"></a>00202                 <span class="comment">/* Setup to process whole image */</span>
<a name="l00203"></a>00203                 istart = 0;
<a name="l00204"></a>00204                 cursrc1 = Src1;
<a name="l00205"></a>00205                 cursrc2 = Src2;
<a name="l00206"></a>00206                 curdst = Dest;
<a name="l00207"></a>00207         }
<a name="l00208"></a>00208 
<a name="l00209"></a>00209         <span class="comment">/* C routine to process image */</span>
<a name="l00210"></a>00210         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l00211"></a>00211                 result = (int) *cursrc1 + (<span class="keywordtype">int</span>) *cursrc2;
<a name="l00212"></a>00212                 <span class="keywordflow">if</span> (result &gt; 255)
<a name="l00213"></a>00213                         result = 255;
<a name="l00214"></a>00214                 *curdst = (<span class="keywordtype">unsigned</span> char) result;
<a name="l00215"></a>00215                 <span class="comment">/* Advance pointers */</span>
<a name="l00216"></a>00216                 cursrc1++;
<a name="l00217"></a>00217                 cursrc2++;
<a name="l00218"></a>00218                 curdst++;
<a name="l00219"></a>00219         }
<a name="l00220"></a>00220 
<a name="l00221"></a>00221         <span class="keywordflow">return</span> (0);
<a name="l00222"></a>00222 }
<a name="l00223"></a>00223 
<a name="l00235"></a>00235 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterMeanMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength,
<a name="l00236"></a>00236                                                    <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Mask)
<a name="l00237"></a>00237 {
<a name="l00238"></a>00238 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l00239"></a>00239 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l00240"></a>00240 <span class="preprocessor"></span>        __asm
<a name="l00241"></a>00241         { 
<a name="l00242"></a>00242                 pusha
<a name="l00243"></a>00243                         mov edx, Mask <span class="comment">/* load Mask address into edx */</span>
<a name="l00244"></a>00244                         movq mm0, [edx] <span class="comment">/* load Mask into mm0 */</span>
<a name="l00245"></a>00245                 mov eax, Src1 <span class="comment">/* load Src1 address into eax */</span>
<a name="l00246"></a>00246                         mov ebx, Src2 <span class="comment">/* load Src2 address into ebx */</span>
<a name="l00247"></a>00247                         mov edi, Dest <span class="comment">/* load Dest address into edi */</span>
<a name="l00248"></a>00248                         mov ecx, SrcLength <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l00249"></a>00249                         shr ecx, 3      <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l00250"></a>00250                         align 16        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l00251"></a>00251 L21011:
<a name="l00252"></a>00252                 movq mm1,  [eax]        <span class="comment">/* load 8 bytes from Src1 into mm1 */</span>
<a name="l00253"></a>00253                 movq mm2,  [ebx]        <span class="comment">/* load 8 bytes from Src2 into mm2 */</span>
<a name="l00254"></a>00254                 <span class="comment">/* --- Byte shift via Word shift --- */</span>
<a name="l00255"></a>00255                 psrlw mm1, 1    <span class="comment">/* shift 4 WORDS of mm1 1 bit to the right */</span>
<a name="l00256"></a>00256                         psrlw mm2, 1    <span class="comment">/* shift 4 WORDS of mm2 1 bit to the right */</span>
<a name="l00257"></a>00257                         pand mm1, mm0   <span class="comment">// apply Mask to 8 BYTES of mm1 */</span>
<a name="l00258"></a>00258                         <span class="comment">/* byte     0x0f, 0xdb, 0xc8 */</span>
<a name="l00259"></a>00259                         pand mm2, mm0   <span class="comment">// apply Mask to 8 BYTES of mm2 */</span>
<a name="l00260"></a>00260                         <span class="comment">/* byte     0x0f, 0xdb, 0xd0 */</span>
<a name="l00261"></a>00261                         paddusb mm1,  mm2       <span class="comment">/* mm1=mm1+mm2 (add 8 bytes with saturation) */</span>
<a name="l00262"></a>00262                         movq [edi],  mm1        <span class="comment">/* store result in Dest */</span>
<a name="l00263"></a>00263                         add eax,  8     <span class="comment">/* increase Src1, Src2 and Dest  */</span>
<a name="l00264"></a>00264                         add ebx,  8     <span class="comment">/* register pointers by 8 */</span>
<a name="l00265"></a>00265                         add edi,  8
<a name="l00266"></a>00266                         dec ecx         <span class="comment">/* decrease loop counter */</span>
<a name="l00267"></a>00267                         jnz L21011      <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l00268"></a>00268                         emms    <span class="comment">/* exit MMX state */</span>
<a name="l00269"></a>00269                         popa
<a name="l00270"></a>00270         }
<a name="l00271"></a>00271 <span class="preprocessor">#else</span>
<a name="l00272"></a>00272 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l00273"></a>00273         __m64 *mSrc1 = (__m64*)Src1;
<a name="l00274"></a>00274         __m64 *mSrc2 = (__m64*)Src2;
<a name="l00275"></a>00275         __m64 *mDest = (__m64*)Dest;
<a name="l00276"></a>00276         __m64 *mMask = (__m64*)Mask;
<a name="l00277"></a>00277         <span class="keywordtype">int</span> i;
<a name="l00278"></a>00278         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l00279"></a>00279                 __m64 mm1 = *mSrc1,
<a name="l00280"></a>00280                       mm2 = *mSrc2;
<a name="l00281"></a>00281                 mm1 = _m_psrlwi(mm1, 1);        <span class="comment">/* shift 4 WORDS of mm1 1 bit to the right */</span>
<a name="l00282"></a>00282                 mm2 = _m_psrlwi(mm2, 1);        <span class="comment">/* shift 4 WORDS of mm2 1 bit to the right */</span>
<a name="l00283"></a>00283                 mm1 = _m_pand(mm1, *mMask);     <span class="comment">/* apply Mask to 8 BYTES of mm1 */</span>
<a name="l00284"></a>00284                 mm2 = _m_pand(mm2, *mMask);     <span class="comment">/* apply Mask to 8 BYTES of mm2 */</span>
<a name="l00285"></a>00285                 *mDest = _m_paddusb(mm1, mm2);  <span class="comment">/* mm1+mm2 (add 8 bytes with saturation) */</span>
<a name="l00286"></a>00286                 mSrc1++;
<a name="l00287"></a>00287                 mSrc2++;
<a name="l00288"></a>00288                 mDest++;
<a name="l00289"></a>00289         }
<a name="l00290"></a>00290         _m_empty();                             <span class="comment">/* clean MMX state */</span>
<a name="l00291"></a>00291 <span class="preprocessor">#endif</span>
<a name="l00292"></a>00292 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l00293"></a>00293 <span class="preprocessor">#else</span>
<a name="l00294"></a>00294 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l00295"></a>00295 <span class="preprocessor">#endif</span>
<a name="l00296"></a>00296 <span class="preprocessor"></span>}
<a name="l00297"></a>00297 
<a name="l00308"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a6012332e1b5c33fad53d71c7848db823">00308</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#ace072118fef77973210eb04fb4bfc779" title="Filter using Mean: D = S1/2 + S2/2.">SDL_imageFilterMean</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
<a name="l00309"></a>00309 {
<a name="l00310"></a>00310         <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Mask[8] = { 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F };
<a name="l00311"></a>00311         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l00312"></a>00312         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *cursrc2, *curdst;
<a name="l00313"></a>00313         <span class="keywordtype">int</span> result;
<a name="l00314"></a>00314 
<a name="l00315"></a>00315         <span class="comment">/* Validate input parameters */</span>
<a name="l00316"></a>00316         <span class="keywordflow">if</span> ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL))
<a name="l00317"></a>00317                 <span class="keywordflow">return</span>(-1);
<a name="l00318"></a>00318         <span class="keywordflow">if</span> (length == 0)
<a name="l00319"></a>00319                 <span class="keywordflow">return</span>(0);
<a name="l00320"></a>00320 
<a name="l00321"></a>00321         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l00322"></a>00322                 <span class="comment">/* MMX routine */</span>
<a name="l00323"></a>00323                 SDL_imageFilterMeanMMX(Src1, Src2, Dest, length, Mask);
<a name="l00324"></a>00324 
<a name="l00325"></a>00325                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l00326"></a>00326                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l00327"></a>00327                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l00328"></a>00328                         istart = length &amp; 0xfffffff8;
<a name="l00329"></a>00329                         cursrc1 = &amp;Src1[istart];
<a name="l00330"></a>00330                         cursrc2 = &amp;Src2[istart];
<a name="l00331"></a>00331                         curdst = &amp;Dest[istart];
<a name="l00332"></a>00332                 } <span class="keywordflow">else</span> {
<a name="l00333"></a>00333                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l00334"></a>00334                         <span class="keywordflow">return</span> (0);
<a name="l00335"></a>00335                 }
<a name="l00336"></a>00336         } <span class="keywordflow">else</span> {
<a name="l00337"></a>00337                 <span class="comment">/* Setup to process whole image */</span>
<a name="l00338"></a>00338                 istart = 0;
<a name="l00339"></a>00339                 cursrc1 = Src1;
<a name="l00340"></a>00340                 cursrc2 = Src2;
<a name="l00341"></a>00341                 curdst = Dest;
<a name="l00342"></a>00342         }
<a name="l00343"></a>00343 
<a name="l00344"></a>00344         <span class="comment">/* C routine to process image */</span>
<a name="l00345"></a>00345         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l00346"></a>00346                 result = (int) *cursrc1 / 2 + (<span class="keywordtype">int</span>) *cursrc2 / 2;
<a name="l00347"></a>00347                 *curdst = (<span class="keywordtype">unsigned</span> char) result;
<a name="l00348"></a>00348                 <span class="comment">/* Advance pointers */</span>
<a name="l00349"></a>00349                 cursrc1++;
<a name="l00350"></a>00350                 cursrc2++;
<a name="l00351"></a>00351                 curdst++;
<a name="l00352"></a>00352         }
<a name="l00353"></a>00353 
<a name="l00354"></a>00354         <span class="keywordflow">return</span> (0);
<a name="l00355"></a>00355 }
<a name="l00356"></a>00356 
<a name="l00367"></a>00367 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterSubMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength)
<a name="l00368"></a>00368 {
<a name="l00369"></a>00369 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l00370"></a>00370 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l00371"></a>00371 <span class="preprocessor"></span>        __asm
<a name="l00372"></a>00372         {
<a name="l00373"></a>00373                 pusha
<a name="l00374"></a>00374                         mov eax,  Src1  <span class="comment">/* load Src1 address into eax */</span>
<a name="l00375"></a>00375                         mov ebx,  Src2  <span class="comment">/* load Src2 address into ebx */</span>
<a name="l00376"></a>00376                         mov edi,  Dest  <span class="comment">/* load Dest address into edi */</span>
<a name="l00377"></a>00377                         mov ecx,  SrcLength     <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l00378"></a>00378                         shr ecx,  3     <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l00379"></a>00379                         align 16 <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l00380"></a>00380 L1012:
<a name="l00381"></a>00381                 movq mm1,  [eax]        <span class="comment">/* load 8 bytes from Src1 into mm1 */</span>
<a name="l00382"></a>00382                 psubusb mm1,  [ebx]     <span class="comment">/* mm1=Src1-Src2 (sub 8 bytes with saturation) */</span>
<a name="l00383"></a>00383                 movq [edi],  mm1        <span class="comment">/* store result in Dest */</span>
<a name="l00384"></a>00384                         add eax, 8      <span class="comment">/* increase Src1, Src2 and Dest  */</span>
<a name="l00385"></a>00385                         add ebx, 8      <span class="comment">/* register pointers by 8 */</span>
<a name="l00386"></a>00386                         add edi, 8
<a name="l00387"></a>00387                         dec ecx <span class="comment">/* decrease loop counter */</span>
<a name="l00388"></a>00388                         jnz L1012       <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l00389"></a>00389                         emms <span class="comment">/* exit MMX state */</span>
<a name="l00390"></a>00390                         popa
<a name="l00391"></a>00391         }
<a name="l00392"></a>00392 <span class="preprocessor">#else</span>
<a name="l00393"></a>00393 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l00394"></a>00394         __m64 *mSrc1 = (__m64*)Src1;
<a name="l00395"></a>00395         __m64 *mSrc2 = (__m64*)Src2;
<a name="l00396"></a>00396         __m64 *mDest = (__m64*)Dest;
<a name="l00397"></a>00397         <span class="keywordtype">int</span> i;
<a name="l00398"></a>00398         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l00399"></a>00399                 *mDest = _m_psubusb(*mSrc1, *mSrc2);    <span class="comment">/* Src1-Src2 (sub 8 bytes with saturation) */</span>
<a name="l00400"></a>00400                 mSrc1++;
<a name="l00401"></a>00401                 mSrc2++;
<a name="l00402"></a>00402                 mDest++;
<a name="l00403"></a>00403         }
<a name="l00404"></a>00404         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l00405"></a>00405 <span class="preprocessor">#endif</span>
<a name="l00406"></a>00406 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l00407"></a>00407 <span class="preprocessor">#else</span>
<a name="l00408"></a>00408 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l00409"></a>00409 <span class="preprocessor">#endif</span>
<a name="l00410"></a>00410 <span class="preprocessor"></span>}
<a name="l00411"></a>00411 
<a name="l00422"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a720893e0f6512aee4dd3875b9c9607b5">00422</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a3c01cf8576ea7a0dfc09dbaa953c9287" title="Filter using Sub: D = saturation0(S1 - S2)">SDL_imageFilterSub</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
<a name="l00423"></a>00423 {
<a name="l00424"></a>00424         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l00425"></a>00425         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *cursrc2, *curdst;
<a name="l00426"></a>00426         <span class="keywordtype">int</span> result;
<a name="l00427"></a>00427 
<a name="l00428"></a>00428         <span class="comment">/* Validate input parameters */</span>
<a name="l00429"></a>00429         <span class="keywordflow">if</span> ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL))
<a name="l00430"></a>00430                 <span class="keywordflow">return</span>(-1);
<a name="l00431"></a>00431         <span class="keywordflow">if</span> (length == 0)
<a name="l00432"></a>00432                 <span class="keywordflow">return</span>(0);
<a name="l00433"></a>00433 
<a name="l00434"></a>00434         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l00435"></a>00435                 <span class="comment">/* MMX routine */</span>
<a name="l00436"></a>00436                 SDL_imageFilterSubMMX(Src1, Src2, Dest, length);
<a name="l00437"></a>00437 
<a name="l00438"></a>00438                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l00439"></a>00439                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l00440"></a>00440                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l00441"></a>00441                         istart = length &amp; 0xfffffff8;
<a name="l00442"></a>00442                         cursrc1 = &amp;Src1[istart];
<a name="l00443"></a>00443                         cursrc2 = &amp;Src2[istart];
<a name="l00444"></a>00444                         curdst = &amp;Dest[istart];
<a name="l00445"></a>00445                 } <span class="keywordflow">else</span> {
<a name="l00446"></a>00446                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l00447"></a>00447                         <span class="keywordflow">return</span> (0);
<a name="l00448"></a>00448                 }
<a name="l00449"></a>00449         } <span class="keywordflow">else</span> {
<a name="l00450"></a>00450                 <span class="comment">/* Setup to process whole image */</span>
<a name="l00451"></a>00451                 istart = 0;
<a name="l00452"></a>00452                 cursrc1 = Src1;
<a name="l00453"></a>00453                 cursrc2 = Src2;
<a name="l00454"></a>00454                 curdst = Dest;
<a name="l00455"></a>00455         }
<a name="l00456"></a>00456 
<a name="l00457"></a>00457         <span class="comment">/* C routine to process image */</span>
<a name="l00458"></a>00458         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l00459"></a>00459                 result = (int) *cursrc1 - (<span class="keywordtype">int</span>) *cursrc2;
<a name="l00460"></a>00460                 <span class="keywordflow">if</span> (result &lt; 0)
<a name="l00461"></a>00461                         result = 0;
<a name="l00462"></a>00462                 *curdst = (<span class="keywordtype">unsigned</span> char) result;
<a name="l00463"></a>00463                 <span class="comment">/* Advance pointers */</span>
<a name="l00464"></a>00464                 cursrc1++;
<a name="l00465"></a>00465                 cursrc2++;
<a name="l00466"></a>00466                 curdst++;
<a name="l00467"></a>00467         }
<a name="l00468"></a>00468 
<a name="l00469"></a>00469         <span class="keywordflow">return</span> (0);
<a name="l00470"></a>00470 }
<a name="l00471"></a>00471 
<a name="l00482"></a>00482 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterAbsDiffMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength)
<a name="l00483"></a>00483 {
<a name="l00484"></a>00484 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l00485"></a>00485 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l00486"></a>00486 <span class="preprocessor"></span>        __asm
<a name="l00487"></a>00487         {
<a name="l00488"></a>00488                 pusha
<a name="l00489"></a>00489                         mov eax, Src1   <span class="comment">/* load Src1 address into eax */</span>
<a name="l00490"></a>00490                         mov ebx, Src2   <span class="comment">/* load Src2 address into ebx */</span>
<a name="l00491"></a>00491                         mov edi, Dest   <span class="comment">/* load Dest address into edi */</span>
<a name="l00492"></a>00492                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l00493"></a>00493                         shr ecx,  3     <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l00494"></a>00494                         align 16        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l00495"></a>00495 L1013:
<a name="l00496"></a>00496                 movq mm1,  [eax]        <span class="comment">/* load 8 bytes from Src1 into mm1 */</span>
<a name="l00497"></a>00497                 movq mm2,  [ebx]        <span class="comment">/* load 8 bytes from Src2 into mm2 */</span>
<a name="l00498"></a>00498                 psubusb mm1,  [ebx]     <span class="comment">/* mm1=Src1-Src2 (sub 8 bytes with saturation) */</span>
<a name="l00499"></a>00499                 psubusb mm2,  [eax]     <span class="comment">/* mm2=Src2-Src1 (sub 8 bytes with saturation) */</span>
<a name="l00500"></a>00500                 por mm1,  mm2   <span class="comment">/* combine both mm2 and mm1 results */</span>
<a name="l00501"></a>00501                         movq [edi],  mm1        <span class="comment">/* store result in Dest */</span>
<a name="l00502"></a>00502                         add eax, 8      <span class="comment">/* increase Src1, Src2 and Dest  */</span>
<a name="l00503"></a>00503                         add ebx, 8      <span class="comment">/* register pointers by 8 */</span>
<a name="l00504"></a>00504                         add edi, 8
<a name="l00505"></a>00505                         dec ecx         <span class="comment">/* decrease loop counter */</span>
<a name="l00506"></a>00506                         jnz L1013       <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l00507"></a>00507                         emms         <span class="comment">/* exit MMX state */</span>
<a name="l00508"></a>00508                         popa
<a name="l00509"></a>00509         }
<a name="l00510"></a>00510 <span class="preprocessor">#else</span>
<a name="l00511"></a>00511 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l00512"></a>00512         __m64 *mSrc1 = (__m64*)Src1;
<a name="l00513"></a>00513         __m64 *mSrc2 = (__m64*)Src2;
<a name="l00514"></a>00514         __m64 *mDest = (__m64*)Dest;
<a name="l00515"></a>00515         <span class="keywordtype">int</span> i;
<a name="l00516"></a>00516         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l00517"></a>00517                 __m64 mm1 = _m_psubusb(*mSrc2, *mSrc1); <span class="comment">/* Src1-Src2 (sub 8 bytes with saturation) */</span>
<a name="l00518"></a>00518                 __m64 mm2 = _m_psubusb(*mSrc1, *mSrc2); <span class="comment">/* Src2-Src1 (sub 8 bytes with saturation) */</span>
<a name="l00519"></a>00519                 *mDest = _m_por(mm1, mm2);              <span class="comment">/* combine both mm2 and mm1 results */</span>
<a name="l00520"></a>00520                 mSrc1++;
<a name="l00521"></a>00521                 mSrc2++;
<a name="l00522"></a>00522                 mDest++;
<a name="l00523"></a>00523         }
<a name="l00524"></a>00524         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l00525"></a>00525 <span class="preprocessor">#endif</span>
<a name="l00526"></a>00526 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l00527"></a>00527 <span class="preprocessor">#else</span>
<a name="l00528"></a>00528 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l00529"></a>00529 <span class="preprocessor">#endif</span>
<a name="l00530"></a>00530 <span class="preprocessor"></span>}
<a name="l00531"></a>00531 
<a name="l00542"></a><a class="code" href="_s_d_l2__image_filter_8h.html#aaa9e8718bcba856ddee135385ebdec26">00542</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a472909f904274255cd6793c520172e48" title="Filter using AbsDiff: D = | S1 - S2 |.">SDL_imageFilterAbsDiff</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
<a name="l00543"></a>00543 {
<a name="l00544"></a>00544         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l00545"></a>00545         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *cursrc2, *curdst;
<a name="l00546"></a>00546         <span class="keywordtype">int</span> result;
<a name="l00547"></a>00547 
<a name="l00548"></a>00548         <span class="comment">/* Validate input parameters */</span>
<a name="l00549"></a>00549         <span class="keywordflow">if</span> ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL))
<a name="l00550"></a>00550                 <span class="keywordflow">return</span>(-1);
<a name="l00551"></a>00551         <span class="keywordflow">if</span> (length == 0)
<a name="l00552"></a>00552                 <span class="keywordflow">return</span>(0);
<a name="l00553"></a>00553 
<a name="l00554"></a>00554         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l00555"></a>00555                 <span class="comment">/* MMX routine */</span>
<a name="l00556"></a>00556                 SDL_imageFilterAbsDiffMMX(Src1, Src2, Dest, length);
<a name="l00557"></a>00557 
<a name="l00558"></a>00558                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l00559"></a>00559                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l00560"></a>00560                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l00561"></a>00561                         istart = length &amp; 0xfffffff8;
<a name="l00562"></a>00562                         cursrc1 = &amp;Src1[istart];
<a name="l00563"></a>00563                         cursrc2 = &amp;Src2[istart];
<a name="l00564"></a>00564                         curdst = &amp;Dest[istart];
<a name="l00565"></a>00565                 } <span class="keywordflow">else</span> {
<a name="l00566"></a>00566                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l00567"></a>00567                         <span class="keywordflow">return</span> (0);
<a name="l00568"></a>00568                 }
<a name="l00569"></a>00569         } <span class="keywordflow">else</span> {
<a name="l00570"></a>00570                 <span class="comment">/* Setup to process whole image */</span>
<a name="l00571"></a>00571                 istart = 0;
<a name="l00572"></a>00572                 cursrc1 = Src1;
<a name="l00573"></a>00573                 cursrc2 = Src2;
<a name="l00574"></a>00574                 curdst = Dest;
<a name="l00575"></a>00575         }
<a name="l00576"></a>00576 
<a name="l00577"></a>00577         <span class="comment">/* C routine to process image */</span>
<a name="l00578"></a>00578         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l00579"></a>00579                 result = abs((<span class="keywordtype">int</span>) *cursrc1 - (<span class="keywordtype">int</span>) *cursrc2);
<a name="l00580"></a>00580                 *curdst = (<span class="keywordtype">unsigned</span> char) result;
<a name="l00581"></a>00581                 <span class="comment">/* Advance pointers */</span>
<a name="l00582"></a>00582                 cursrc1++;
<a name="l00583"></a>00583                 cursrc2++;
<a name="l00584"></a>00584                 curdst++;
<a name="l00585"></a>00585         }
<a name="l00586"></a>00586 
<a name="l00587"></a>00587         <span class="keywordflow">return</span> (0);
<a name="l00588"></a>00588 }
<a name="l00589"></a>00589 
<a name="l00600"></a>00600 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterMultMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength)
<a name="l00601"></a>00601 {
<a name="l00602"></a>00602 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l00603"></a>00603 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l00604"></a>00604 <span class="preprocessor"></span>        __asm
<a name="l00605"></a>00605         {
<a name="l00606"></a>00606                 pusha
<a name="l00607"></a>00607                         mov eax, Src1   <span class="comment">/* load Src1 address into eax */</span>
<a name="l00608"></a>00608                         mov ebx, Src2   <span class="comment">/* load Src2 address into ebx */</span>
<a name="l00609"></a>00609                         mov edi, Dest   <span class="comment">/* load Dest address into edi */</span>
<a name="l00610"></a>00610                         mov ecx, SrcLength   <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l00611"></a>00611                         shr ecx, 3   <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l00612"></a>00612                         pxor mm0, mm0   <span class="comment">/* zero mm0 register */</span>
<a name="l00613"></a>00613                         align 16        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l00614"></a>00614 L1014:
<a name="l00615"></a>00615                 movq mm1, [eax]   <span class="comment">/* load 8 bytes from Src1 into mm1 */</span>
<a name="l00616"></a>00616                 movq mm3, [ebx]   <span class="comment">/* load 8 bytes from Src2 into mm3 */</span>
<a name="l00617"></a>00617                 movq mm2, mm1   <span class="comment">/* copy mm1 into mm2 */</span>
<a name="l00618"></a>00618                         movq mm4, mm3   <span class="comment">/* copy mm3 into mm4  */</span>
<a name="l00619"></a>00619                         punpcklbw mm1, mm0   <span class="comment">/* unpack low  bytes of Src1 into words */</span>
<a name="l00620"></a>00620                         punpckhbw mm2, mm0   <span class="comment">/* unpack high bytes of Src1 into words */</span>
<a name="l00621"></a>00621                         punpcklbw mm3, mm0   <span class="comment">/* unpack low  bytes of Src2 into words */</span>
<a name="l00622"></a>00622                         punpckhbw mm4, mm0   <span class="comment">/* unpack high bytes of Src2 into words */</span>
<a name="l00623"></a>00623                         pmullw mm1, mm3   <span class="comment">/* mul low  bytes of Src1 and Src2  */</span>
<a name="l00624"></a>00624                         pmullw mm2, mm4   <span class="comment">/* mul high bytes of Src1 and Src2 */</span>
<a name="l00625"></a>00625                         <span class="comment">/* Take abs value of the results (signed words) */</span>
<a name="l00626"></a>00626                         movq mm5, mm1   <span class="comment">/* copy mm1 into mm5 */</span>
<a name="l00627"></a>00627                         movq mm6, mm2   <span class="comment">/* copy mm2 into mm6 */</span>
<a name="l00628"></a>00628                         psraw mm5, 15   <span class="comment">/* fill mm5 words with word sign bit */</span>
<a name="l00629"></a>00629                         psraw mm6, 15   <span class="comment">/* fill mm6 words with word sign bit */</span>
<a name="l00630"></a>00630                         pxor mm1, mm5   <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l00631"></a>00631                         pxor mm2, mm6   <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l00632"></a>00632                         psubsw mm1, mm5   <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l00633"></a>00633                         psubsw mm2, mm6   <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l00634"></a>00634                         packuswb mm1, mm2   <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l00635"></a>00635                         movq [edi], mm1   <span class="comment">/* store result in Dest */</span>
<a name="l00636"></a>00636                         add eax, 8   <span class="comment">/* increase Src1, Src2 and Dest  */</span>
<a name="l00637"></a>00637                         add ebx, 8   <span class="comment">/* register pointers by 8 */</span>
<a name="l00638"></a>00638                         add edi, 8
<a name="l00639"></a>00639                         dec ecx         <span class="comment">/* decrease loop counter */</span>
<a name="l00640"></a>00640                         jnz L1014       <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l00641"></a>00641                         emms <span class="comment">/* exit MMX state */</span>
<a name="l00642"></a>00642                         popa
<a name="l00643"></a>00643         }
<a name="l00644"></a>00644 <span class="preprocessor">#else</span>
<a name="l00645"></a>00645 <span class="preprocessor"></span>        <span class="comment">/* i386 ASM with constraints: */</span>
<a name="l00646"></a>00646         <span class="comment">/* asm volatile ( */</span>
<a name="l00647"></a>00647         <span class="comment">/*      &quot;shr $3, %%ecx \n\t&quot;    /\* counter/8 (MMX loads 8 bytes at a time) *\/ */</span>
<a name="l00648"></a>00648         <span class="comment">/*      &quot;pxor      %%mm0, %%mm0 \n\t&quot;   /\* zero mm0 register *\/ */</span>
<a name="l00649"></a>00649         <span class="comment">/*      &quot;.align 16       \n\t&quot;  /\* 16 byte alignment of the loop entry *\/ */</span>
<a name="l00650"></a>00650         <span class="comment">/*      &quot;1: movq (%%eax), %%mm1 \n\t&quot;     /\* load 8 bytes from Src1 into mm1 *\/ */</span>
<a name="l00651"></a>00651         <span class="comment">/*      &quot;movq    (%%ebx), %%mm3 \n\t&quot;   /\* load 8 bytes from Src2 into mm3 *\/ */</span>
<a name="l00652"></a>00652         <span class="comment">/*      &quot;movq      %%mm1, %%mm2 \n\t&quot;   /\* copy mm1 into mm2 *\/ */</span>
<a name="l00653"></a>00653         <span class="comment">/*      &quot;movq      %%mm3, %%mm4 \n\t&quot;   /\* copy mm3 into mm4  *\/ */</span>
<a name="l00654"></a>00654         <span class="comment">/*      &quot;punpcklbw %%mm0, %%mm1 \n\t&quot;   /\* unpack low  bytes of Src1 into words *\/ */</span>
<a name="l00655"></a>00655         <span class="comment">/*      &quot;punpckhbw %%mm0, %%mm2 \n\t&quot;   /\* unpack high bytes of Src1 into words *\/ */</span>
<a name="l00656"></a>00656         <span class="comment">/*      &quot;punpcklbw %%mm0, %%mm3 \n\t&quot;   /\* unpack low  bytes of Src2 into words *\/ */</span>
<a name="l00657"></a>00657         <span class="comment">/*      &quot;punpckhbw %%mm0, %%mm4 \n\t&quot;   /\* unpack high bytes of Src2 into words *\/ */</span>
<a name="l00658"></a>00658         <span class="comment">/*      &quot;pmullw    %%mm3, %%mm1 \n\t&quot;   /\* mul low  bytes of Src1 and Src2  *\/ */</span>
<a name="l00659"></a>00659         <span class="comment">/*      &quot;pmullw    %%mm4, %%mm2 \n\t&quot;   /\* mul high bytes of Src1 and Src2 *\/ */</span>
<a name="l00660"></a>00660         <span class="comment">/*      /\* Take abs value of the results (signed words) *\/ */</span>
<a name="l00661"></a>00661         <span class="comment">/*      &quot;movq      %%mm1, %%mm5 \n\t&quot;   /\* copy mm1 into mm5 *\/ */</span>
<a name="l00662"></a>00662         <span class="comment">/*      &quot;movq      %%mm2, %%mm6 \n\t&quot;   /\* copy mm2 into mm6 *\/ */</span>
<a name="l00663"></a>00663         <span class="comment">/*      &quot;psraw       $15, %%mm5 \n\t&quot;   /\* fill mm5 words with word sign bit *\/ */</span>
<a name="l00664"></a>00664         <span class="comment">/*      &quot;psraw       $15, %%mm6 \n\t&quot;   /\* fill mm6 words with word sign bit *\/ */</span>
<a name="l00665"></a>00665         <span class="comment">/*      &quot;pxor      %%mm5, %%mm1 \n\t&quot;   /\* take 1&#39;s compliment of only neg. words *\/ */</span>
<a name="l00666"></a>00666         <span class="comment">/*      &quot;pxor      %%mm6, %%mm2 \n\t&quot;   /\* take 1&#39;s compliment of only neg. words *\/ */</span>
<a name="l00667"></a>00667         <span class="comment">/*      &quot;psubsw    %%mm5, %%mm1 \n\t&quot;   /\* add 1 to only neg. words, W-(-1) or W-0 *\/ */</span>
<a name="l00668"></a>00668         <span class="comment">/*      &quot;psubsw    %%mm6, %%mm2 \n\t&quot;   /\* add 1 to only neg. words, W-(-1) or W-0 *\/ */</span>
<a name="l00669"></a>00669         <span class="comment">/*      &quot;packuswb  %%mm2, %%mm1 \n\t&quot;   /\* pack words back into bytes with saturation *\/ */</span>
<a name="l00670"></a>00670         <span class="comment">/*      &quot;movq    %%mm1, (%%edi) \n\t&quot;   /\* store result in Dest *\/ */</span>
<a name="l00671"></a>00671         <span class="comment">/*      &quot;add $8, %%eax \n\t&quot;    /\* increase Src1, Src2 and Dest  *\/ */</span>
<a name="l00672"></a>00672         <span class="comment">/*      &quot;add $8, %%ebx \n\t&quot;    /\* register pointers by 8 *\/ */</span>
<a name="l00673"></a>00673         <span class="comment">/*      &quot;add $8, %%edi \n\t&quot; */</span>
<a name="l00674"></a>00674         <span class="comment">/*      &quot;dec %%ecx     \n\t&quot;    /\* decrease loop counter *\/ */</span>
<a name="l00675"></a>00675         <span class="comment">/*      &quot;jnz 1b        \n\t&quot;    /\* check loop termination, proceed if required *\/ */</span>
<a name="l00676"></a>00676         <span class="comment">/*      &quot;emms          \n\t&quot;    /\* exit MMX state *\/ */</span>
<a name="l00677"></a>00677         <span class="comment">/*      : &quot;+a&quot; (Src1),          /\* load Src1 address into rax, modified by the loop *\/ */</span>
<a name="l00678"></a>00678         <span class="comment">/*        &quot;+b&quot; (Src2),          /\* load Src2 address into rbx, modified by the loop *\/ */</span>
<a name="l00679"></a>00679         <span class="comment">/*        &quot;+c&quot; (SrcLength),     /\* load loop counter (SIZE) into rcx, modified by the loop *\/ */</span>
<a name="l00680"></a>00680         <span class="comment">/*        &quot;+D&quot; (Dest)           /\* load Dest address into rdi, modified by the loop *\/ */</span>
<a name="l00681"></a>00681         <span class="comment">/*      : */</span>
<a name="l00682"></a>00682         <span class="comment">/*      : &quot;memory&quot;,             /\* *Dest is modified *\/ */</span>
<a name="l00683"></a>00683         <span class="comment">/*           &quot;mm0&quot;,&quot;mm1&quot;,&quot;mm2&quot;,&quot;mm3&quot;,&quot;mm4&quot;,&quot;mm5&quot;,&quot;mm6&quot;  /\* registers modified *\/ */</span>
<a name="l00684"></a>00684         <span class="comment">/* ); */</span>
<a name="l00685"></a>00685 
<a name="l00686"></a>00686         <span class="comment">/* i386 and x86_64 */</span>
<a name="l00687"></a>00687         __m64 *mSrc1 = (__m64*)Src1;
<a name="l00688"></a>00688         __m64 *mSrc2 = (__m64*)Src2;
<a name="l00689"></a>00689         __m64 *mDest = (__m64*)Dest;
<a name="l00690"></a>00690         __m64 mm0 = _m_from_int(0); <span class="comment">/* zero mm0 register */</span>
<a name="l00691"></a>00691         <span class="keywordtype">int</span> i;
<a name="l00692"></a>00692         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l00693"></a>00693                 __m64 mm1, mm2, mm3, mm4, mm5, mm6;
<a name="l00694"></a>00694                 mm1 = _m_punpcklbw(*mSrc1, mm0);        <span class="comment">/* unpack low  bytes of Src1 into words */</span>
<a name="l00695"></a>00695                 mm2 = _m_punpckhbw(*mSrc1, mm0);        <span class="comment">/* unpack high bytes of Src1 into words */</span>
<a name="l00696"></a>00696                 mm3 = _m_punpcklbw(*mSrc2, mm0);        <span class="comment">/* unpack low  bytes of Src2 into words */</span>
<a name="l00697"></a>00697                 mm4 = _m_punpckhbw(*mSrc2, mm0);        <span class="comment">/* unpack high bytes of Src2 into words */</span>
<a name="l00698"></a>00698                 mm1 = _m_pmullw(mm1, mm3);              <span class="comment">/* mul low  bytes of Src1 and Src2  */</span>
<a name="l00699"></a>00699                 mm2 = _m_pmullw(mm2, mm4);              <span class="comment">/* mul high bytes of Src1 and Src2 */</span>
<a name="l00700"></a>00700                 mm5 = _m_psrawi(mm1, 15);               <span class="comment">/* fill mm5 words with word sign bit */</span>
<a name="l00701"></a>00701                 mm6 = _m_psrawi(mm2, 15);               <span class="comment">/* fill mm6 words with word sign bit */</span>
<a name="l00702"></a>00702                 mm1 = _m_pxor(mm1, mm5);                <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l00703"></a>00703                 mm2 = _m_pxor(mm2, mm6);                <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l00704"></a>00704                 mm1 = _m_psubsw(mm1, mm5);              <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l00705"></a>00705                 mm2 = _m_psubsw(mm2, mm6);              <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l00706"></a>00706                 *mDest = _m_packuswb(mm1, mm2);         <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l00707"></a>00707                 mSrc1++;
<a name="l00708"></a>00708                 mSrc2++;
<a name="l00709"></a>00709                 mDest++;
<a name="l00710"></a>00710         }
<a name="l00711"></a>00711         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l00712"></a>00712 <span class="preprocessor">#endif</span>
<a name="l00713"></a>00713 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l00714"></a>00714 <span class="preprocessor">#else</span>
<a name="l00715"></a>00715 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l00716"></a>00716 <span class="preprocessor">#endif</span>
<a name="l00717"></a>00717 <span class="preprocessor"></span>}
<a name="l00718"></a>00718 
<a name="l00729"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a1966f22bee81045917e776fd64821051">00729</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#af4633031d40a9ea0956a2f3c6c87a384" title="Filter using Mult: D = saturation255(S1 * S2)">SDL_imageFilterMult</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
<a name="l00730"></a>00730 {
<a name="l00731"></a>00731         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l00732"></a>00732         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *cursrc2, *curdst;
<a name="l00733"></a>00733         <span class="keywordtype">int</span> result;
<a name="l00734"></a>00734 
<a name="l00735"></a>00735         <span class="comment">/* Validate input parameters */</span>
<a name="l00736"></a>00736         <span class="keywordflow">if</span> ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL))
<a name="l00737"></a>00737                 <span class="keywordflow">return</span>(-1);
<a name="l00738"></a>00738         <span class="keywordflow">if</span> (length == 0)
<a name="l00739"></a>00739                 <span class="keywordflow">return</span>(0);
<a name="l00740"></a>00740 
<a name="l00741"></a>00741         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l00742"></a>00742                 <span class="comment">/* MMX routine */</span>
<a name="l00743"></a>00743                 SDL_imageFilterMultMMX(Src1, Src2, Dest, length);
<a name="l00744"></a>00744 
<a name="l00745"></a>00745                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l00746"></a>00746                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l00747"></a>00747                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l00748"></a>00748                         istart = length &amp; 0xfffffff8;
<a name="l00749"></a>00749                         cursrc1 = &amp;Src1[istart];
<a name="l00750"></a>00750                         cursrc2 = &amp;Src2[istart];
<a name="l00751"></a>00751                         curdst = &amp;Dest[istart];
<a name="l00752"></a>00752                 } <span class="keywordflow">else</span> {
<a name="l00753"></a>00753                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l00754"></a>00754                         <span class="keywordflow">return</span> (0);
<a name="l00755"></a>00755                 }
<a name="l00756"></a>00756         } <span class="keywordflow">else</span> {
<a name="l00757"></a>00757                 <span class="comment">/* Setup to process whole image */</span>
<a name="l00758"></a>00758                 istart = 0;
<a name="l00759"></a>00759                 cursrc1 = Src1;
<a name="l00760"></a>00760                 cursrc2 = Src2;
<a name="l00761"></a>00761                 curdst = Dest;
<a name="l00762"></a>00762         }
<a name="l00763"></a>00763 
<a name="l00764"></a>00764         <span class="comment">/* C routine to process image */</span>
<a name="l00765"></a>00765         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l00766"></a>00766 
<a name="l00767"></a>00767                 <span class="comment">/* NOTE: this is probably wrong - dunno what the MMX code does */</span>
<a name="l00768"></a>00768 
<a name="l00769"></a>00769                 result = (int) *cursrc1 * (<span class="keywordtype">int</span>) *cursrc2;
<a name="l00770"></a>00770                 <span class="keywordflow">if</span> (result &gt; 255)
<a name="l00771"></a>00771                         result = 255;
<a name="l00772"></a>00772                 *curdst = (<span class="keywordtype">unsigned</span> char) result;
<a name="l00773"></a>00773                 <span class="comment">/* Advance pointers */</span>
<a name="l00774"></a>00774                 cursrc1++;
<a name="l00775"></a>00775                 cursrc2++;
<a name="l00776"></a>00776                 curdst++;
<a name="l00777"></a>00777         }
<a name="l00778"></a>00778 
<a name="l00779"></a>00779         <span class="keywordflow">return</span> (0);
<a name="l00780"></a>00780 }
<a name="l00781"></a>00781 
<a name="l00792"></a><a class="code" href="_s_d_l2__image_filter_8c.html#a346db972dff9c56e3c45c904eaa3c39a">00792</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a346db972dff9c56e3c45c904eaa3c39a" title="Internal ASM Filter using MultNor: D = S1 * S2.">SDL_imageFilterMultNorASM</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength)
<a name="l00793"></a>00793 {
<a name="l00794"></a>00794 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l00795"></a>00795 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l00796"></a>00796 <span class="preprocessor"></span>        __asm
<a name="l00797"></a>00797         {
<a name="l00798"></a>00798                 pusha
<a name="l00799"></a>00799                         mov edx, Src1   <span class="comment">/* load Src1 address into edx */</span>
<a name="l00800"></a>00800                         mov esi, Src2   <span class="comment">/* load Src2 address into esi */</span>
<a name="l00801"></a>00801                         mov edi, Dest   <span class="comment">/* load Dest address into edi */</span>
<a name="l00802"></a>00802                         mov ecx, SrcLength   <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l00803"></a>00803                         align 16        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l00804"></a>00804 L10141:
<a name="l00805"></a>00805                 mov al, [edx]   <span class="comment">/* load a byte from Src1 */</span>
<a name="l00806"></a>00806                 mul [esi]       <span class="comment">/* mul with a byte from Src2 */</span>
<a name="l00807"></a>00807                 mov [edi], al   <span class="comment">/* move a byte result to Dest */</span>
<a name="l00808"></a>00808                         inc edx         <span class="comment">/* increment Src1, Src2, Dest */</span>
<a name="l00809"></a>00809                         inc esi                 <span class="comment">/* pointer registers by one */</span>
<a name="l00810"></a>00810                         inc edi
<a name="l00811"></a>00811                         dec ecx <span class="comment">/* decrease loop counter */</span>
<a name="l00812"></a>00812                         jnz L10141      <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l00813"></a>00813                         popa
<a name="l00814"></a>00814         }
<a name="l00815"></a>00815 <span class="preprocessor">#else</span>
<a name="l00816"></a>00816 <span class="preprocessor"></span>        <span class="comment">/* Note: ~5% gain on i386, less efficient than C on x86_64 */</span>
<a name="l00817"></a>00817         <span class="comment">/* Also depends on whether this function is static (?!) */</span>
<a name="l00818"></a>00818         <span class="keyword">asm</span> <span class="keyword">volatile</span> (
<a name="l00819"></a>00819                 <span class="stringliteral">&quot;.align 16       \n\t&quot;</span>  <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l00820"></a>00820 <span class="preprocessor">#  if defined(i386)</span>
<a name="l00821"></a>00821 <span class="preprocessor"></span>                <span class="stringliteral">&quot;1:mov  (%%edx), %%al \n\t&quot;</span>      <span class="comment">/* load a byte from Src1 */</span>
<a name="l00822"></a>00822                 <span class="stringliteral">&quot;mulb (%%esi)       \n\t&quot;</span>       <span class="comment">/* mul with a byte from Src2 */</span>
<a name="l00823"></a>00823                 <span class="stringliteral">&quot;mov %%al, (%%edi)  \n\t&quot;</span>       <span class="comment">/* move a byte result to Dest */</span>
<a name="l00824"></a>00824                 <span class="stringliteral">&quot;inc %%edx \n\t&quot;</span>                <span class="comment">/* increment Src1, Src2, Dest */</span>
<a name="l00825"></a>00825                 <span class="stringliteral">&quot;inc %%esi \n\t&quot;</span>                <span class="comment">/* pointer registers by one */</span>
<a name="l00826"></a>00826                 <span class="stringliteral">&quot;inc %%edi \n\t&quot;</span>
<a name="l00827"></a>00827                 <span class="stringliteral">&quot;dec %%ecx      \n\t&quot;</span>   <span class="comment">/* decrease loop counter */</span>
<a name="l00828"></a>00828 <span class="preprocessor">#  elif defined(__x86_64__)</span>
<a name="l00829"></a>00829 <span class="preprocessor"></span>                <span class="stringliteral">&quot;1:mov  (%%rdx), %%al \n\t&quot;</span>      <span class="comment">/* load a byte from Src1 */</span>
<a name="l00830"></a>00830                 <span class="stringliteral">&quot;mulb (%%rsi)       \n\t&quot;</span>       <span class="comment">/* mul with a byte from Src2 */</span>
<a name="l00831"></a>00831                 <span class="stringliteral">&quot;mov %%al, (%%rdi)  \n\t&quot;</span>       <span class="comment">/* move a byte result to Dest */</span>
<a name="l00832"></a>00832                 <span class="stringliteral">&quot;inc %%rdx \n\t&quot;</span>                <span class="comment">/* increment Src1, Src2, Dest */</span>
<a name="l00833"></a>00833                 <span class="stringliteral">&quot;inc %%rsi \n\t&quot;</span>                <span class="comment">/* pointer registers by one */</span>
<a name="l00834"></a>00834                 <span class="stringliteral">&quot;inc %%rdi \n\t&quot;</span>
<a name="l00835"></a>00835                 <span class="stringliteral">&quot;dec %%rcx      \n\t&quot;</span>   <span class="comment">/* decrease loop counter */</span>
<a name="l00836"></a>00836 <span class="preprocessor">#  endif</span>
<a name="l00837"></a>00837 <span class="preprocessor"></span>                <span class="stringliteral">&quot;jnz 1b         \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l00838"></a>00838                 : <span class="stringliteral">&quot;+d&quot;</span> (Src1),          <span class="comment">/* load Src1 address into edx */</span>
<a name="l00839"></a>00839                   <span class="stringliteral">&quot;+S&quot;</span> (Src2),          <span class="comment">/* load Src2 address into esi */</span>
<a name="l00840"></a>00840                   <span class="stringliteral">&quot;+c&quot;</span> (SrcLength),     <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l00841"></a>00841                   <span class="stringliteral">&quot;+D&quot;</span> (Dest)           <span class="comment">/* load Dest address into edi */</span>
<a name="l00842"></a>00842                 :
<a name="l00843"></a>00843                 : <span class="stringliteral">&quot;memory&quot;</span>, <span class="stringliteral">&quot;rax&quot;</span>
<a name="l00844"></a>00844                 );
<a name="l00845"></a>00845 <span class="preprocessor">#endif</span>
<a name="l00846"></a>00846 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l00847"></a>00847 <span class="preprocessor">#else</span>
<a name="l00848"></a>00848 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l00849"></a>00849 <span class="preprocessor">#endif</span>
<a name="l00850"></a>00850 <span class="preprocessor"></span>}
<a name="l00851"></a>00851 
<a name="l00862"></a><a class="code" href="_s_d_l2__image_filter_8h.html#aff3256626208bfc490268cf07e8a29af">00862</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a5f3c9fd40426bb46eba5ac167505dcc5" title="Filter using MultNor: D = S1 * S2.">SDL_imageFilterMultNor</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
<a name="l00863"></a>00863 {
<a name="l00864"></a>00864         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l00865"></a>00865         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *cursrc2, *curdst;
<a name="l00866"></a>00866 
<a name="l00867"></a>00867         <span class="comment">/* Validate input parameters */</span>
<a name="l00868"></a>00868         <span class="keywordflow">if</span> ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL))
<a name="l00869"></a>00869                 <span class="keywordflow">return</span>(-1);
<a name="l00870"></a>00870         <span class="keywordflow">if</span> (length == 0)
<a name="l00871"></a>00871                 <span class="keywordflow">return</span>(0);
<a name="l00872"></a>00872 
<a name="l00873"></a>00873         <span class="keywordflow">if</span> (<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) {
<a name="l00874"></a>00874                 <span class="keywordflow">if</span> (length &gt; 0) {
<a name="l00875"></a>00875                         <span class="comment">/* ASM routine */</span>
<a name="l00876"></a>00876                         <a class="code" href="_s_d_l2__image_filter_8c.html#a346db972dff9c56e3c45c904eaa3c39a" title="Internal ASM Filter using MultNor: D = S1 * S2.">SDL_imageFilterMultNorASM</a>(Src1, Src2, Dest, length);
<a name="l00877"></a>00877 
<a name="l00878"></a>00878                         <span class="comment">/* Check for unaligned bytes */</span>
<a name="l00879"></a>00879                         <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l00880"></a>00880                                 <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l00881"></a>00881                                 istart = length &amp; 0xfffffff8;
<a name="l00882"></a>00882                                 cursrc1 = &amp;Src1[istart];
<a name="l00883"></a>00883                                 cursrc2 = &amp;Src2[istart];
<a name="l00884"></a>00884                                 curdst = &amp;Dest[istart];
<a name="l00885"></a>00885                         } <span class="keywordflow">else</span> {
<a name="l00886"></a>00886                                 <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l00887"></a>00887                                 <span class="keywordflow">return</span> (0);
<a name="l00888"></a>00888                         }
<a name="l00889"></a>00889                 } <span class="keywordflow">else</span> {
<a name="l00890"></a>00890                         <span class="comment">/* No bytes - we are done */</span>
<a name="l00891"></a>00891                         <span class="keywordflow">return</span> (0);
<a name="l00892"></a>00892                 }
<a name="l00893"></a>00893         } <span class="keywordflow">else</span> {
<a name="l00894"></a>00894                 <span class="comment">/* Setup to process whole image */</span>
<a name="l00895"></a>00895                 istart = 0;
<a name="l00896"></a>00896                 cursrc1 = Src1;
<a name="l00897"></a>00897                 cursrc2 = Src2;
<a name="l00898"></a>00898                 curdst = Dest;
<a name="l00899"></a>00899         }
<a name="l00900"></a>00900 
<a name="l00901"></a>00901         <span class="comment">/* C routine to process image */</span>
<a name="l00902"></a>00902         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l00903"></a>00903                 *curdst = (int)*cursrc1 * (<span class="keywordtype">int</span>)*cursrc2;  <span class="comment">// (int) for efficiency</span>
<a name="l00904"></a>00904                 <span class="comment">/* Advance pointers */</span>
<a name="l00905"></a>00905                 cursrc1++;
<a name="l00906"></a>00906                 cursrc2++;
<a name="l00907"></a>00907                 curdst++;
<a name="l00908"></a>00908         }
<a name="l00909"></a>00909 
<a name="l00910"></a>00910         <span class="keywordflow">return</span> (0);
<a name="l00911"></a>00911 }
<a name="l00912"></a>00912 
<a name="l00923"></a>00923 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterMultDivby2MMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength)
<a name="l00924"></a>00924 {
<a name="l00925"></a>00925 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l00926"></a>00926 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l00927"></a>00927 <span class="preprocessor"></span>        __asm
<a name="l00928"></a>00928         { 
<a name="l00929"></a>00929                 pusha
<a name="l00930"></a>00930                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l00931"></a>00931                         mov ebx, Src2           <span class="comment">/* load Src2 address into ebx */</span>
<a name="l00932"></a>00932                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l00933"></a>00933                         mov ecx,  SrcLength     <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l00934"></a>00934                         shr ecx,  3     <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l00935"></a>00935                         pxor mm0,  mm0  <span class="comment">/* zero mm0 register */</span>
<a name="l00936"></a>00936                         align 16                <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l00937"></a>00937 L1015:
<a name="l00938"></a>00938                 movq mm1,  [eax]        <span class="comment">/* load 8 bytes from Src1 into mm1 */</span>
<a name="l00939"></a>00939                 movq mm3,  [ebx]        <span class="comment">/* load 8 bytes from Src2 into mm3 */</span>
<a name="l00940"></a>00940                 movq mm2,  mm1  <span class="comment">/* copy mm1 into mm2 */</span>
<a name="l00941"></a>00941                         movq mm4,  mm3  <span class="comment">/* copy mm3 into mm4  */</span>
<a name="l00942"></a>00942                         punpcklbw mm1,  mm0     <span class="comment">/* unpack low  bytes of Src1 into words */</span>
<a name="l00943"></a>00943                         punpckhbw mm2,  mm0     <span class="comment">/* unpack high bytes of Src1 into words */</span>
<a name="l00944"></a>00944                         punpcklbw mm3,  mm0     <span class="comment">/* unpack low  bytes of Src2 into words */</span>
<a name="l00945"></a>00945                         punpckhbw mm4,  mm0     <span class="comment">/* unpack high bytes of Src2 into words */</span>
<a name="l00946"></a>00946                         psrlw mm1,  1   <span class="comment">/* divide mm1 words by 2, Src1 low bytes */</span>
<a name="l00947"></a>00947                         psrlw mm2,  1   <span class="comment">/* divide mm2 words by 2, Src1 high bytes */</span>
<a name="l00948"></a>00948                         pmullw mm1,  mm3        <span class="comment">/* mul low  bytes of Src1 and Src2  */</span>
<a name="l00949"></a>00949                         pmullw mm2,  mm4        <span class="comment">/* mul high bytes of Src1 and Src2 */</span>
<a name="l00950"></a>00950                         packuswb mm1,  mm2      <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l00951"></a>00951                         movq [edi],  mm1        <span class="comment">/* store result in Dest */</span>
<a name="l00952"></a>00952                         add eax,  8     <span class="comment">/* increase Src1, Src2 and Dest  */</span>
<a name="l00953"></a>00953                         add ebx,  8     <span class="comment">/* register pointers by 8 */</span>
<a name="l00954"></a>00954                         add edi,  8
<a name="l00955"></a>00955                         dec ecx         <span class="comment">/* decrease loop counter */</span>
<a name="l00956"></a>00956                         jnz L1015               <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l00957"></a>00957                         emms                    <span class="comment">/* exit MMX state */</span>
<a name="l00958"></a>00958                         popa
<a name="l00959"></a>00959         }
<a name="l00960"></a>00960 <span class="preprocessor">#else</span>
<a name="l00961"></a>00961 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l00962"></a>00962         __m64 *mSrc1 = (__m64*)Src1;
<a name="l00963"></a>00963         __m64 *mSrc2 = (__m64*)Src2;
<a name="l00964"></a>00964         __m64 *mDest = (__m64*)Dest;
<a name="l00965"></a>00965         __m64 mm0 = _m_from_int(0); <span class="comment">/* zero mm0 register */</span>
<a name="l00966"></a>00966         <span class="keywordtype">int</span> i;
<a name="l00967"></a>00967         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l00968"></a>00968                 __m64 mm1, mm2, mm3, mm4, mm5, mm6;
<a name="l00969"></a>00969                 mm1 = _m_punpcklbw(*mSrc1, mm0);        <span class="comment">/* unpack low  bytes of Src1 into words */</span>
<a name="l00970"></a>00970                 mm2 = _m_punpckhbw(*mSrc1, mm0);        <span class="comment">/* unpack high bytes of Src1 into words */</span>
<a name="l00971"></a>00971                 mm3 = _m_punpcklbw(*mSrc2, mm0);        <span class="comment">/* unpack low  bytes of Src2 into words */</span>
<a name="l00972"></a>00972                 mm4 = _m_punpckhbw(*mSrc2, mm0);        <span class="comment">/* unpack high bytes of Src2 into words */</span>
<a name="l00973"></a>00973                 mm1 = _m_psrlwi(mm1, 1);                <span class="comment">/* divide mm1 words by 2, Src1 low bytes */</span>
<a name="l00974"></a>00974                 mm2 = _m_psrlwi(mm2, 1);                <span class="comment">/* divide mm2 words by 2, Src1 high bytes */</span>
<a name="l00975"></a>00975                 mm1 = _m_pmullw(mm1, mm3);              <span class="comment">/* mul low  bytes of Src1 and Src2  */</span>
<a name="l00976"></a>00976                 mm2 = _m_pmullw(mm2, mm4);              <span class="comment">/* mul high bytes of Src1 and Src2 */</span>
<a name="l00977"></a>00977                 *mDest = _m_packuswb(mm1, mm2);         <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l00978"></a>00978                 mSrc1++;
<a name="l00979"></a>00979                 mSrc2++;
<a name="l00980"></a>00980                 mDest++;
<a name="l00981"></a>00981         }
<a name="l00982"></a>00982         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l00983"></a>00983 <span class="preprocessor">#endif</span>
<a name="l00984"></a>00984 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l00985"></a>00985 <span class="preprocessor">#else</span>
<a name="l00986"></a>00986 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l00987"></a>00987 <span class="preprocessor">#endif</span>
<a name="l00988"></a>00988 <span class="preprocessor"></span>}
<a name="l00989"></a>00989 
<a name="l01000"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a462b662e34e0ea7f1da83fb493f9d9f5">01000</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a80737f6427c7bdb30d39a92f6524fc14" title="Filter using MultDivby2: D = saturation255(S1/2 * S2)">SDL_imageFilterMultDivby2</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
<a name="l01001"></a>01001 {
<a name="l01002"></a>01002         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l01003"></a>01003         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *cursrc2, *curdst;
<a name="l01004"></a>01004         <span class="keywordtype">int</span> result;
<a name="l01005"></a>01005 
<a name="l01006"></a>01006         <span class="comment">/* Validate input parameters */</span>
<a name="l01007"></a>01007         <span class="keywordflow">if</span> ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL))
<a name="l01008"></a>01008                 <span class="keywordflow">return</span>(-1);
<a name="l01009"></a>01009         <span class="keywordflow">if</span> (length == 0)
<a name="l01010"></a>01010                 <span class="keywordflow">return</span>(0);
<a name="l01011"></a>01011 
<a name="l01012"></a>01012         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l01013"></a>01013                 <span class="comment">/* MMX routine */</span>
<a name="l01014"></a>01014                 SDL_imageFilterMultDivby2MMX(Src1, Src2, Dest, length);
<a name="l01015"></a>01015 
<a name="l01016"></a>01016                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l01017"></a>01017                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l01018"></a>01018                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l01019"></a>01019                         istart = length &amp; 0xfffffff8;
<a name="l01020"></a>01020                         cursrc1 = &amp;Src1[istart];
<a name="l01021"></a>01021                         cursrc2 = &amp;Src2[istart];
<a name="l01022"></a>01022                         curdst = &amp;Dest[istart];
<a name="l01023"></a>01023                 } <span class="keywordflow">else</span> {
<a name="l01024"></a>01024                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l01025"></a>01025                         <span class="keywordflow">return</span> (0);
<a name="l01026"></a>01026                 }
<a name="l01027"></a>01027         } <span class="keywordflow">else</span> {
<a name="l01028"></a>01028                 <span class="comment">/* Setup to process whole image */</span>
<a name="l01029"></a>01029                 istart = 0;
<a name="l01030"></a>01030                 cursrc1 = Src1;
<a name="l01031"></a>01031                 cursrc2 = Src2;
<a name="l01032"></a>01032                 curdst = Dest;
<a name="l01033"></a>01033         }
<a name="l01034"></a>01034 
<a name="l01035"></a>01035         <span class="comment">/* C routine to process image */</span>
<a name="l01036"></a>01036         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l01037"></a>01037                 result = ((int) *cursrc1 / 2) * (int) *cursrc2;
<a name="l01038"></a>01038                 <span class="keywordflow">if</span> (result &gt; 255)
<a name="l01039"></a>01039                         result = 255;
<a name="l01040"></a>01040                 *curdst = (<span class="keywordtype">unsigned</span> char) result;
<a name="l01041"></a>01041                 <span class="comment">/* Advance pointers */</span>
<a name="l01042"></a>01042                 cursrc1++;
<a name="l01043"></a>01043                 cursrc2++;
<a name="l01044"></a>01044                 curdst++;
<a name="l01045"></a>01045         }
<a name="l01046"></a>01046 
<a name="l01047"></a>01047         <span class="keywordflow">return</span> (0);
<a name="l01048"></a>01048 }
<a name="l01049"></a>01049 
<a name="l01060"></a>01060 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterMultDivby4MMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength)
<a name="l01061"></a>01061 {
<a name="l01062"></a>01062 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l01063"></a>01063 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l01064"></a>01064 <span class="preprocessor"></span>        __asm
<a name="l01065"></a>01065         {
<a name="l01066"></a>01066                 pusha
<a name="l01067"></a>01067                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l01068"></a>01068                         mov ebx, Src2           <span class="comment">/* load Src2 address into ebx */</span>
<a name="l01069"></a>01069                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l01070"></a>01070                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l01071"></a>01071                         shr ecx,  3     <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l01072"></a>01072                         pxor mm0, mm0           <span class="comment">/* zero mm0 register */</span>
<a name="l01073"></a>01073                         align 16                <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l01074"></a>01074 L1016:
<a name="l01075"></a>01075                 movq mm1, [eax]         <span class="comment">/* load 8 bytes from Src1 into mm1 */</span>
<a name="l01076"></a>01076                 movq mm3, [ebx]         <span class="comment">/* load 8 bytes from Src2 into mm3 */</span>
<a name="l01077"></a>01077                 movq mm2, mm1           <span class="comment">/* copy mm1 into mm2 */</span>
<a name="l01078"></a>01078                         movq mm4, mm3           <span class="comment">/* copy mm3 into mm4  */</span>
<a name="l01079"></a>01079                         punpcklbw mm1, mm0      <span class="comment">/* unpack low  bytes of Src1 into words */</span>
<a name="l01080"></a>01080                         punpckhbw mm2, mm0      <span class="comment">/* unpack high bytes of Src1 into words */</span>
<a name="l01081"></a>01081                         punpcklbw mm3, mm0      <span class="comment">/* unpack low  bytes of Src2 into words */</span>
<a name="l01082"></a>01082                         punpckhbw mm4, mm0      <span class="comment">/* unpack high bytes of Src2 into words */</span>
<a name="l01083"></a>01083                         psrlw mm1, 1    <span class="comment">/* divide mm1 words by 2, Src1 low bytes */</span>
<a name="l01084"></a>01084                         psrlw mm2, 1    <span class="comment">/* divide mm2 words by 2, Src1 high bytes */</span>
<a name="l01085"></a>01085                         psrlw mm3, 1    <span class="comment">/* divide mm3 words by 2, Src2 low bytes */</span>
<a name="l01086"></a>01086                         psrlw mm4, 1    <span class="comment">/* divide mm4 words by 2, Src2 high bytes */</span>
<a name="l01087"></a>01087                         pmullw mm1, mm3         <span class="comment">/* mul low  bytes of Src1 and Src2  */</span>
<a name="l01088"></a>01088                         pmullw mm2, mm4         <span class="comment">/* mul high bytes of Src1 and Src2 */</span>
<a name="l01089"></a>01089                         packuswb mm1, mm2       <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l01090"></a>01090                         movq [edi], mm1         <span class="comment">/* store result in Dest */</span>
<a name="l01091"></a>01091                         add eax, 8      <span class="comment">/* increase Src1, Src2 and Dest  */</span>
<a name="l01092"></a>01092                         add ebx, 8      <span class="comment">/* register pointers by 8 */</span>
<a name="l01093"></a>01093                         add edi,  8
<a name="l01094"></a>01094                         dec ecx         <span class="comment">/* decrease loop counter */</span>
<a name="l01095"></a>01095                         jnz L1016               <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l01096"></a>01096                         emms                    <span class="comment">/* exit MMX state */</span>
<a name="l01097"></a>01097                         popa
<a name="l01098"></a>01098         }
<a name="l01099"></a>01099 <span class="preprocessor">#else</span>
<a name="l01100"></a>01100 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l01101"></a>01101         __m64 *mSrc1 = (__m64*)Src1;
<a name="l01102"></a>01102         __m64 *mSrc2 = (__m64*)Src2;
<a name="l01103"></a>01103         __m64 *mDest = (__m64*)Dest;
<a name="l01104"></a>01104         __m64 mm0 = _m_from_int(0); <span class="comment">/* zero mm0 register */</span>
<a name="l01105"></a>01105         <span class="keywordtype">int</span> i;
<a name="l01106"></a>01106         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l01107"></a>01107                 __m64 mm1, mm2, mm3, mm4, mm5, mm6;
<a name="l01108"></a>01108                 mm1 = _m_punpcklbw(*mSrc1, mm0);        <span class="comment">/* unpack low  bytes of Src1 into words */</span>
<a name="l01109"></a>01109                 mm2 = _m_punpckhbw(*mSrc1, mm0);        <span class="comment">/* unpack high bytes of Src1 into words */</span>
<a name="l01110"></a>01110                 mm3 = _m_punpcklbw(*mSrc2, mm0);        <span class="comment">/* unpack low  bytes of Src2 into words */</span>
<a name="l01111"></a>01111                 mm4 = _m_punpckhbw(*mSrc2, mm0);        <span class="comment">/* unpack high bytes of Src2 into words */</span>
<a name="l01112"></a>01112                 mm1 = _m_psrlwi(mm1, 1);                <span class="comment">/* divide mm1 words by 2, Src1 low bytes */</span>
<a name="l01113"></a>01113                 mm2 = _m_psrlwi(mm2, 1);                <span class="comment">/* divide mm2 words by 2, Src1 high bytes */</span>
<a name="l01114"></a>01114                 mm3 = _m_psrlwi(mm3, 1);                <span class="comment">/* divide mm3 words by 2, Src2 low bytes */</span>
<a name="l01115"></a>01115                 mm4 = _m_psrlwi(mm4, 1);                <span class="comment">/* divide mm4 words by 2, Src2 high bytes */</span>
<a name="l01116"></a>01116                 mm1 = _m_pmullw(mm1, mm3);              <span class="comment">/* mul low  bytes of Src1 and Src2  */</span>
<a name="l01117"></a>01117                 mm2 = _m_pmullw(mm2, mm4);              <span class="comment">/* mul high bytes of Src1 and Src2 */</span>
<a name="l01118"></a>01118                 *mDest = _m_packuswb(mm1, mm2);         <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l01119"></a>01119                 mSrc1++;
<a name="l01120"></a>01120                 mSrc2++;
<a name="l01121"></a>01121                 mDest++;
<a name="l01122"></a>01122         }
<a name="l01123"></a>01123         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l01124"></a>01124 <span class="preprocessor">#endif</span>
<a name="l01125"></a>01125 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l01126"></a>01126 <span class="preprocessor">#else</span>
<a name="l01127"></a>01127 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l01128"></a>01128 <span class="preprocessor">#endif</span>
<a name="l01129"></a>01129 <span class="preprocessor"></span>}
<a name="l01130"></a>01130 
<a name="l01141"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a52e4de0e4818b4256c189f35e68e1242">01141</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a30e685653eb1050c7d48feaeb8f801a1" title="Filter using MultDivby4: D = saturation255(S1/2 * S2/2)">SDL_imageFilterMultDivby4</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
<a name="l01142"></a>01142 {
<a name="l01143"></a>01143         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l01144"></a>01144         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *cursrc2, *curdst;
<a name="l01145"></a>01145         <span class="keywordtype">int</span> result;
<a name="l01146"></a>01146 
<a name="l01147"></a>01147         <span class="comment">/* Validate input parameters */</span>
<a name="l01148"></a>01148         <span class="keywordflow">if</span> ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL))
<a name="l01149"></a>01149                 <span class="keywordflow">return</span>(-1);
<a name="l01150"></a>01150         <span class="keywordflow">if</span> (length == 0)
<a name="l01151"></a>01151                 <span class="keywordflow">return</span>(0);
<a name="l01152"></a>01152 
<a name="l01153"></a>01153         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l01154"></a>01154                 <span class="comment">/* MMX routine */</span>
<a name="l01155"></a>01155                 SDL_imageFilterMultDivby4MMX(Src1, Src2, Dest, length);
<a name="l01156"></a>01156 
<a name="l01157"></a>01157                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l01158"></a>01158                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l01159"></a>01159                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l01160"></a>01160                         istart = length &amp; 0xfffffff8;
<a name="l01161"></a>01161                         cursrc1 = &amp;Src1[istart];
<a name="l01162"></a>01162                         cursrc2 = &amp;Src2[istart];
<a name="l01163"></a>01163                         curdst = &amp;Dest[istart];
<a name="l01164"></a>01164                 } <span class="keywordflow">else</span> {
<a name="l01165"></a>01165                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l01166"></a>01166                         <span class="keywordflow">return</span> (0);
<a name="l01167"></a>01167                 }
<a name="l01168"></a>01168         } <span class="keywordflow">else</span> {
<a name="l01169"></a>01169                 <span class="comment">/* Setup to process whole image */</span>
<a name="l01170"></a>01170                 istart = 0;
<a name="l01171"></a>01171                 cursrc1 = Src1;
<a name="l01172"></a>01172                 cursrc2 = Src2;
<a name="l01173"></a>01173                 curdst = Dest;
<a name="l01174"></a>01174         }
<a name="l01175"></a>01175 
<a name="l01176"></a>01176         <span class="comment">/* C routine to process image */</span>
<a name="l01177"></a>01177         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l01178"></a>01178                 result = ((int) *cursrc1 / 2) * ((int) *cursrc2 / 2);
<a name="l01179"></a>01179                 <span class="keywordflow">if</span> (result &gt; 255)
<a name="l01180"></a>01180                         result = 255;
<a name="l01181"></a>01181                 *curdst = (<span class="keywordtype">unsigned</span> char) result;
<a name="l01182"></a>01182                 <span class="comment">/* Advance pointers */</span>
<a name="l01183"></a>01183                 cursrc1++;
<a name="l01184"></a>01184                 cursrc2++;
<a name="l01185"></a>01185                 curdst++;
<a name="l01186"></a>01186         }
<a name="l01187"></a>01187 
<a name="l01188"></a>01188         <span class="keywordflow">return</span> (0);
<a name="l01189"></a>01189 }
<a name="l01190"></a>01190 
<a name="l01201"></a>01201 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterBitAndMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength)
<a name="l01202"></a>01202 {
<a name="l01203"></a>01203 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l01204"></a>01204 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l01205"></a>01205 <span class="preprocessor"></span>        __asm
<a name="l01206"></a>01206         {
<a name="l01207"></a>01207                 pusha
<a name="l01208"></a>01208                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l01209"></a>01209                         mov ebx, Src2           <span class="comment">/* load Src2 address into ebx */</span>
<a name="l01210"></a>01210                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l01211"></a>01211                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l01212"></a>01212                         shr ecx, 3      <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l01213"></a>01213                         align 16                <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l01214"></a>01214 L1017:
<a name="l01215"></a>01215                 movq mm1, [eax]         <span class="comment">/* load 8 bytes from Src1 into mm1 */</span>
<a name="l01216"></a>01216                 pand mm1, [ebx]         <span class="comment">/* mm1=Src1&amp;Src2 */</span>
<a name="l01217"></a>01217                 movq [edi], mm1         <span class="comment">/* store result in Dest */</span>
<a name="l01218"></a>01218                         add eax, 8      <span class="comment">/* increase Src1, Src2 and Dest  */</span>
<a name="l01219"></a>01219                         add ebx, 8      <span class="comment">/* register pointers by 8 */</span>
<a name="l01220"></a>01220                         add edi, 8
<a name="l01221"></a>01221                         dec ecx         <span class="comment">/* decrease loop counter */</span>
<a name="l01222"></a>01222                         jnz L1017               <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l01223"></a>01223                         emms                    <span class="comment">/* exit MMX state */</span>
<a name="l01224"></a>01224                         popa
<a name="l01225"></a>01225         }
<a name="l01226"></a>01226 <span class="preprocessor">#else</span>
<a name="l01227"></a>01227 <span class="preprocessor"></span>        <span class="comment">/* x86_64 ASM with constraints: */</span>
<a name="l01228"></a>01228         <span class="comment">/* asm volatile ( */</span>
<a name="l01229"></a>01229         <span class="comment">/*      &quot;shr $3, %%rcx \n\t&quot;    /\* counter/8 (MMX loads 8 bytes at a time) *\/ */</span>
<a name="l01230"></a>01230         <span class="comment">/*      &quot;.align 16       \n\t&quot;  /\* 16 byte alignment of the loop entry *\/ */</span>
<a name="l01231"></a>01231         <span class="comment">/*      &quot;1: movq (%%rax), %%mm1 \n\t&quot;   /\* load 8 bytes from Src1 into mm1 *\/ */</span>
<a name="l01232"></a>01232         <span class="comment">/*      &quot;pand    (%%rbx), %%mm1 \n\t&quot;   /\* mm1=Src1&amp;Src2 *\/ */</span>
<a name="l01233"></a>01233         <span class="comment">/*      &quot;movq    %%mm1, (%%rdi) \n\t&quot;   /\* store result in Dest *\/ */</span>
<a name="l01234"></a>01234         <span class="comment">/*      &quot;add $8, %%rax \n\t&quot;    /\* increase Src1, Src2 and Dest  *\/ */</span>
<a name="l01235"></a>01235         <span class="comment">/*      &quot;add $8, %%rbx \n\t&quot;    /\* register pointers by 8 *\/ */</span>
<a name="l01236"></a>01236         <span class="comment">/*      &quot;add $8, %%rdi \n\t&quot; */</span>
<a name="l01237"></a>01237         <span class="comment">/*      &quot;dec %%rcx     \n\t&quot;    /\* decrease loop counter *\/ */</span>
<a name="l01238"></a>01238         <span class="comment">/*      &quot;jnz 1b        \n\t&quot;    /\* check loop termination, proceed if required *\/ */</span>
<a name="l01239"></a>01239         <span class="comment">/*      &quot;emms          \n\t&quot;    /\* exit MMX state *\/ */</span>
<a name="l01240"></a>01240         <span class="comment">/*      : &quot;+a&quot; (Src1),          /\* load Src1 address into rax, modified by the loop *\/ */</span>
<a name="l01241"></a>01241         <span class="comment">/*        &quot;+b&quot; (Src2),          /\* load Src2 address into rbx, modified by the loop *\/ */</span>
<a name="l01242"></a>01242         <span class="comment">/*        &quot;+c&quot; (SrcLength),     /\* load loop counter (SIZE) into rcx, modified by the loop *\/ */</span>
<a name="l01243"></a>01243         <span class="comment">/*        &quot;+D&quot; (Dest)           /\* load Dest address into rdi, modified by the loop *\/ */</span>
<a name="l01244"></a>01244         <span class="comment">/*      : */</span>
<a name="l01245"></a>01245         <span class="comment">/*      : &quot;memory&quot;,             /\* *Dest is modified *\/ */</span>
<a name="l01246"></a>01246         <span class="comment">/*           &quot;mm1&quot;                      /\* register mm1 modified *\/ */</span>
<a name="l01247"></a>01247         <span class="comment">/* ); */</span>
<a name="l01248"></a>01248 
<a name="l01249"></a>01249         <span class="comment">/* i386 and x86_64 */</span>
<a name="l01250"></a>01250         __m64 *mSrc1 = (__m64*)Src1;
<a name="l01251"></a>01251         __m64 *mSrc2 = (__m64*)Src2;
<a name="l01252"></a>01252         __m64 *mDest = (__m64*)Dest;
<a name="l01253"></a>01253         <span class="keywordtype">int</span> i;
<a name="l01254"></a>01254         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l01255"></a>01255                 *mDest = _m_pand(*mSrc1, *mSrc2);       <span class="comment">/* Src1&amp;Src2 */</span>
<a name="l01256"></a>01256                 mSrc1++;
<a name="l01257"></a>01257                 mSrc2++;
<a name="l01258"></a>01258                 mDest++;
<a name="l01259"></a>01259         }
<a name="l01260"></a>01260         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l01261"></a>01261 <span class="preprocessor">#endif</span>
<a name="l01262"></a>01262 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l01263"></a>01263 <span class="preprocessor">#else</span>
<a name="l01264"></a>01264 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l01265"></a>01265 <span class="preprocessor">#endif</span>
<a name="l01266"></a>01266 <span class="preprocessor"></span>}
<a name="l01267"></a>01267 
<a name="l01278"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a47a7564f857e42dcc2e3b5f8cd2943a9">01278</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a85837ce1b5de1f907b6b9053922b5cbc" title="Filter using BitAnd: D = S1 &amp; S2.">SDL_imageFilterBitAnd</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
<a name="l01279"></a>01279 {
<a name="l01280"></a>01280         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l01281"></a>01281         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *cursrc2, *curdst;
<a name="l01282"></a>01282 
<a name="l01283"></a>01283         <span class="comment">/* Validate input parameters */</span>
<a name="l01284"></a>01284         <span class="keywordflow">if</span> ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL))
<a name="l01285"></a>01285                 <span class="keywordflow">return</span>(-1);
<a name="l01286"></a>01286         <span class="keywordflow">if</span> (length == 0)
<a name="l01287"></a>01287                 <span class="keywordflow">return</span>(0);
<a name="l01288"></a>01288 
<a name="l01289"></a>01289         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()&gt;0) &amp;&amp; (length&gt;7)) {
<a name="l01290"></a>01290                 <span class="comment">/*  if (length &gt; 7) { */</span>
<a name="l01291"></a>01291                 <span class="comment">/* Call MMX routine */</span>
<a name="l01292"></a>01292 
<a name="l01293"></a>01293                 SDL_imageFilterBitAndMMX(Src1, Src2, Dest, length);
<a name="l01294"></a>01294 
<a name="l01295"></a>01295                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l01296"></a>01296                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l01297"></a>01297 
<a name="l01298"></a>01298                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l01299"></a>01299                         istart = length &amp; 0xfffffff8;
<a name="l01300"></a>01300                         cursrc1 = &amp;Src1[istart];
<a name="l01301"></a>01301                         cursrc2 = &amp;Src2[istart];
<a name="l01302"></a>01302                         curdst = &amp;Dest[istart];
<a name="l01303"></a>01303                 } <span class="keywordflow">else</span> {
<a name="l01304"></a>01304                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l01305"></a>01305                         <span class="keywordflow">return</span> (0);
<a name="l01306"></a>01306                 }
<a name="l01307"></a>01307         } <span class="keywordflow">else</span> {
<a name="l01308"></a>01308                 <span class="comment">/* Setup to process whole image */</span>
<a name="l01309"></a>01309                 istart = 0;
<a name="l01310"></a>01310                 cursrc1 = Src1;
<a name="l01311"></a>01311                 cursrc2 = Src2;
<a name="l01312"></a>01312                 curdst = Dest;
<a name="l01313"></a>01313         }
<a name="l01314"></a>01314 
<a name="l01315"></a>01315         <span class="comment">/* C routine to process image */</span>
<a name="l01316"></a>01316         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l01317"></a>01317                 *curdst = (*cursrc1) &amp; (*cursrc2);
<a name="l01318"></a>01318                 <span class="comment">/* Advance pointers */</span>
<a name="l01319"></a>01319                 cursrc1++;
<a name="l01320"></a>01320                 cursrc2++;
<a name="l01321"></a>01321                 curdst++;
<a name="l01322"></a>01322         }
<a name="l01323"></a>01323 
<a name="l01324"></a>01324         <span class="keywordflow">return</span> (0);
<a name="l01325"></a>01325 }
<a name="l01326"></a>01326 
<a name="l01337"></a>01337 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterBitOrMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength)
<a name="l01338"></a>01338 {
<a name="l01339"></a>01339 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l01340"></a>01340 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l01341"></a>01341 <span class="preprocessor"></span>        __asm
<a name="l01342"></a>01342         {
<a name="l01343"></a>01343                 pusha
<a name="l01344"></a>01344                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l01345"></a>01345                         mov ebx, Src2           <span class="comment">/* load Src2 address into ebx */</span>
<a name="l01346"></a>01346                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l01347"></a>01347                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l01348"></a>01348                         shr ecx,  3     <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l01349"></a>01349                         align 16                <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l01350"></a>01350 L91017:
<a name="l01351"></a>01351                 movq mm1, [eax]         <span class="comment">/* load 8 bytes from Src1 into mm1 */</span>
<a name="l01352"></a>01352                 por mm1, [ebx]          <span class="comment">/* mm1=Src1|Src2 */</span>
<a name="l01353"></a>01353                 movq [edi], mm1         <span class="comment">/* store result in Dest */</span>
<a name="l01354"></a>01354                         add eax, 8      <span class="comment">/* increase Src1, Src2 and Dest  */</span>
<a name="l01355"></a>01355                         add ebx, 8      <span class="comment">/* register pointers by 8 */</span>
<a name="l01356"></a>01356                         add edi,  8
<a name="l01357"></a>01357                         dec ecx         <span class="comment">/* decrease loop counter */</span>
<a name="l01358"></a>01358                         jnz L91017              <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l01359"></a>01359                         emms                    <span class="comment">/* exit MMX state */</span>
<a name="l01360"></a>01360                         popa
<a name="l01361"></a>01361         }
<a name="l01362"></a>01362 <span class="preprocessor">#else</span>
<a name="l01363"></a>01363 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l01364"></a>01364         __m64 *mSrc1 = (__m64*)Src1;
<a name="l01365"></a>01365         __m64 *mSrc2 = (__m64*)Src2;
<a name="l01366"></a>01366         __m64 *mDest = (__m64*)Dest;
<a name="l01367"></a>01367         <span class="keywordtype">int</span> i;
<a name="l01368"></a>01368         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l01369"></a>01369                 *mDest = _m_por(*mSrc1, *mSrc2);        <span class="comment">/* Src1|Src2 */</span>
<a name="l01370"></a>01370                 mSrc1++;
<a name="l01371"></a>01371                 mSrc2++;
<a name="l01372"></a>01372                 mDest++;
<a name="l01373"></a>01373         }
<a name="l01374"></a>01374         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l01375"></a>01375 <span class="preprocessor">#endif</span>
<a name="l01376"></a>01376 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l01377"></a>01377 <span class="preprocessor">#else</span>
<a name="l01378"></a>01378 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l01379"></a>01379 <span class="preprocessor">#endif</span>
<a name="l01380"></a>01380 <span class="preprocessor"></span>}
<a name="l01381"></a>01381 
<a name="l01392"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a7c6288c51dcf074b4ba8f1bf0c349f02">01392</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a5cf1c477f4e32d02f74ee95d9f7b0021" title="Filter using BitOr: D = S1 | S2.">SDL_imageFilterBitOr</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
<a name="l01393"></a>01393 {
<a name="l01394"></a>01394         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l01395"></a>01395         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *cursrc2, *curdst;
<a name="l01396"></a>01396 
<a name="l01397"></a>01397         <span class="comment">/* Validate input parameters */</span>
<a name="l01398"></a>01398         <span class="keywordflow">if</span> ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL))
<a name="l01399"></a>01399                 <span class="keywordflow">return</span>(-1);
<a name="l01400"></a>01400         <span class="keywordflow">if</span> (length == 0)
<a name="l01401"></a>01401                 <span class="keywordflow">return</span>(0);
<a name="l01402"></a>01402 
<a name="l01403"></a>01403         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l01404"></a>01404 
<a name="l01405"></a>01405                 <span class="comment">/* MMX routine */</span>
<a name="l01406"></a>01406                 SDL_imageFilterBitOrMMX(Src1, Src2, Dest, length);
<a name="l01407"></a>01407 
<a name="l01408"></a>01408                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l01409"></a>01409                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l01410"></a>01410                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l01411"></a>01411                         istart = length &amp; 0xfffffff8;
<a name="l01412"></a>01412                         cursrc1 = &amp;Src1[istart];
<a name="l01413"></a>01413                         cursrc2 = &amp;Src2[istart];
<a name="l01414"></a>01414                         curdst = &amp;Dest[istart];
<a name="l01415"></a>01415                 } <span class="keywordflow">else</span> {
<a name="l01416"></a>01416                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l01417"></a>01417                         <span class="keywordflow">return</span> (0);
<a name="l01418"></a>01418                 }
<a name="l01419"></a>01419         } <span class="keywordflow">else</span> {
<a name="l01420"></a>01420                 <span class="comment">/* Setup to process whole image */</span>
<a name="l01421"></a>01421                 istart = 0;
<a name="l01422"></a>01422                 cursrc1 = Src1;
<a name="l01423"></a>01423                 cursrc2 = Src2;
<a name="l01424"></a>01424                 curdst = Dest;
<a name="l01425"></a>01425         }
<a name="l01426"></a>01426 
<a name="l01427"></a>01427         <span class="comment">/* C routine to process image */</span>
<a name="l01428"></a>01428         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l01429"></a>01429                 *curdst = *cursrc1 | *cursrc2;
<a name="l01430"></a>01430                 <span class="comment">/* Advance pointers */</span>
<a name="l01431"></a>01431                 cursrc1++;
<a name="l01432"></a>01432                 cursrc2++;
<a name="l01433"></a>01433                 curdst++;
<a name="l01434"></a>01434         }
<a name="l01435"></a>01435         <span class="keywordflow">return</span> (0);
<a name="l01436"></a>01436 }
<a name="l01437"></a>01437 
<a name="l01448"></a>01448 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterDivASM(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength)
<a name="l01449"></a>01449 {
<a name="l01450"></a>01450 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l01451"></a>01451 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l01452"></a>01452 <span class="preprocessor"></span>        __asm
<a name="l01453"></a>01453         {
<a name="l01454"></a>01454                 pusha
<a name="l01455"></a>01455                         mov edx, Src1           <span class="comment">/* load Src1 address into edx */</span>
<a name="l01456"></a>01456                         mov esi, Src2           <span class="comment">/* load Src2 address into esi */</span>
<a name="l01457"></a>01457                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l01458"></a>01458                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l01459"></a>01459                         align 16                <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l01460"></a>01460 L10191:
<a name="l01461"></a>01461                 mov bl, [esi]           <span class="comment">/* load a byte from Src2 */</span>
<a name="l01462"></a>01462                 cmp bl, 0       <span class="comment">/* check if it zero */</span>
<a name="l01463"></a>01463                         jnz L10192
<a name="l01464"></a>01464                         mov [edi], 255          <span class="comment">/* division by zero = 255 !!! */</span>
<a name="l01465"></a>01465                         jmp  L10193
<a name="l01466"></a>01466 L10192:
<a name="l01467"></a>01467                 xor ah, ah      <span class="comment">/* prepare AX, zero AH register */</span>
<a name="l01468"></a>01468                         mov al, [edx]           <span class="comment">/* load a byte from Src1 into AL */</span>
<a name="l01469"></a>01469                 div   bl                <span class="comment">/* divide AL by BL */</span>
<a name="l01470"></a>01470                         mov [edi], al           <span class="comment">/* move a byte result to Dest */</span>
<a name="l01471"></a>01471 L10193:
<a name="l01472"></a>01472                 inc edx         <span class="comment">/* increment Src1, Src2, Dest */</span>
<a name="l01473"></a>01473                         inc esi                 <span class="comment">/* pointer registers by one */</span>
<a name="l01474"></a>01474                         inc edi
<a name="l01475"></a>01475                         dec ecx         <span class="comment">/* decrease loop counter */</span>
<a name="l01476"></a>01476                         jnz L10191      <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l01477"></a>01477                         popa
<a name="l01478"></a>01478         }
<a name="l01479"></a>01479 <span class="preprocessor">#else</span>
<a name="l01480"></a>01480 <span class="preprocessor"></span>        <span class="comment">/* Note: ~15% gain on i386, less efficient than C on x86_64 */</span>
<a name="l01481"></a>01481         <span class="comment">/* Also depends on whether the function is static (?!) */</span>
<a name="l01482"></a>01482         <span class="comment">/* Also depends on whether we work on malloc() or static char[] */</span>
<a name="l01483"></a>01483         <span class="keyword">asm</span> <span class="keyword">volatile</span> (
<a name="l01484"></a>01484 <span class="preprocessor">#  if defined(i386)</span>
<a name="l01485"></a>01485 <span class="preprocessor"></span>                <span class="stringliteral">&quot;pushl %%ebx \n\t&quot;</span>              <span class="comment">/* %ebx may be the PIC register.  */</span>
<a name="l01486"></a>01486                 <span class="stringliteral">&quot;.align 16     \n\t&quot;</span>            <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l01487"></a>01487                 <span class="stringliteral">&quot;1: mov (%%esi), %%bl  \n\t&quot;</span>    <span class="comment">/* load a byte from Src2 */</span>
<a name="l01488"></a>01488                 <span class="stringliteral">&quot;cmp       $0, %%bl    \n\t&quot;</span>    <span class="comment">/* check if it zero */</span>
<a name="l01489"></a>01489                 <span class="stringliteral">&quot;jnz 2f                \n\t&quot;</span>
<a name="l01490"></a>01490                 <span class="stringliteral">&quot;movb  $255, (%%edi)   \n\t&quot;</span>    <span class="comment">/* division by zero = 255 !!! */</span>
<a name="l01491"></a>01491                 <span class="stringliteral">&quot;jmp 3f                \n\t&quot;</span>
<a name="l01492"></a>01492                 <span class="stringliteral">&quot;2: xor %%ah, %%ah     \n\t&quot;</span>    <span class="comment">/* prepare AX, zero AH register */</span>
<a name="l01493"></a>01493                 <span class="stringliteral">&quot;mov   (%%edx), %%al   \n\t&quot;</span>    <span class="comment">/* load a byte from Src1 into AL */</span>
<a name="l01494"></a>01494                 <span class="stringliteral">&quot;div   %%bl            \n\t&quot;</span>    <span class="comment">/* divide AL by BL */</span>
<a name="l01495"></a>01495                 <span class="stringliteral">&quot;mov   %%al, (%%edi)   \n\t&quot;</span>    <span class="comment">/* move a byte result to Dest */</span>
<a name="l01496"></a>01496                 <span class="stringliteral">&quot;3: inc %%edx          \n\t&quot;</span>    <span class="comment">/* increment Src1, Src2, Dest */</span>
<a name="l01497"></a>01497                 <span class="stringliteral">&quot;inc %%esi \n\t&quot;</span>                <span class="comment">/* pointer registers by one */</span>
<a name="l01498"></a>01498                 <span class="stringliteral">&quot;inc %%edi \n\t&quot;</span>
<a name="l01499"></a>01499                 <span class="stringliteral">&quot;dec %%ecx \n\t&quot;</span>                <span class="comment">/* decrease loop counter */</span>
<a name="l01500"></a>01500                 <span class="stringliteral">&quot;jnz 1b    \n\t&quot;</span>                <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l01501"></a>01501                 <span class="stringliteral">&quot;popl %%ebx \n\t&quot;</span>               <span class="comment">/* restore %ebx */</span>
<a name="l01502"></a>01502                 : <span class="stringliteral">&quot;+d&quot;</span> (Src1),          <span class="comment">/* load Src1 address into edx */</span>
<a name="l01503"></a>01503                   <span class="stringliteral">&quot;+S&quot;</span> (Src2),          <span class="comment">/* load Src2 address into esi */</span>
<a name="l01504"></a>01504                   <span class="stringliteral">&quot;+c&quot;</span> (SrcLength),     <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l01505"></a>01505                   <span class="stringliteral">&quot;+D&quot;</span> (Dest)           <span class="comment">/* load Dest address into edi */</span>
<a name="l01506"></a>01506                 :
<a name="l01507"></a>01507                 : <span class="stringliteral">&quot;memory&quot;</span>, <span class="stringliteral">&quot;rax&quot;</span>
<a name="l01508"></a>01508 <span class="preprocessor">#  elif defined(__x86_64__)</span>
<a name="l01509"></a>01509 <span class="preprocessor"></span>                <span class="stringliteral">&quot;.align 16     \n\t&quot;</span>            <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l01510"></a>01510                 <span class="stringliteral">&quot;1: mov (%%rsi), %%bl  \n\t&quot;</span>    <span class="comment">/* load a byte from Src2 */</span>
<a name="l01511"></a>01511                 <span class="stringliteral">&quot;cmp       $0, %%bl    \n\t&quot;</span>    <span class="comment">/* check if it zero */</span>
<a name="l01512"></a>01512                 <span class="stringliteral">&quot;jnz 2f                \n\t&quot;</span>
<a name="l01513"></a>01513                 <span class="stringliteral">&quot;movb  $255, (%%rdi)   \n\t&quot;</span>    <span class="comment">/* division by zero = 255 !!! */</span>
<a name="l01514"></a>01514                 <span class="stringliteral">&quot;jmp 3f                \n\t&quot;</span>
<a name="l01515"></a>01515                 <span class="stringliteral">&quot;2: xor %%ah, %%ah     \n\t&quot;</span>    <span class="comment">/* prepare AX, zero AH register */</span>
<a name="l01516"></a>01516                 <span class="stringliteral">&quot;mov   (%%rdx), %%al   \n\t&quot;</span>    <span class="comment">/* load a byte from Src1 into AL */</span>
<a name="l01517"></a>01517                 <span class="stringliteral">&quot;div   %%bl            \n\t&quot;</span>    <span class="comment">/* divide AL by BL */</span>
<a name="l01518"></a>01518                 <span class="stringliteral">&quot;mov   %%al, (%%rdi)   \n\t&quot;</span>    <span class="comment">/* move a byte result to Dest */</span>
<a name="l01519"></a>01519                 <span class="stringliteral">&quot;3: inc %%rdx          \n\t&quot;</span>    <span class="comment">/* increment Src1, Src2, Dest */</span>
<a name="l01520"></a>01520                 <span class="stringliteral">&quot;inc %%rsi \n\t&quot;</span>                <span class="comment">/* pointer registers by one */</span>
<a name="l01521"></a>01521                 <span class="stringliteral">&quot;inc %%rdi \n\t&quot;</span>
<a name="l01522"></a>01522                 <span class="stringliteral">&quot;dec %%rcx \n\t&quot;</span>                <span class="comment">/* decrease loop counter */</span>
<a name="l01523"></a>01523                 <span class="stringliteral">&quot;jnz 1b    \n\t&quot;</span>                <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l01524"></a>01524                 : <span class="stringliteral">&quot;+d&quot;</span> (Src1),          <span class="comment">/* load Src1 address into edx */</span>
<a name="l01525"></a>01525                   <span class="stringliteral">&quot;+S&quot;</span> (Src2),          <span class="comment">/* load Src2 address into esi */</span>
<a name="l01526"></a>01526                   <span class="stringliteral">&quot;+c&quot;</span> (SrcLength),     <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l01527"></a>01527                   <span class="stringliteral">&quot;+D&quot;</span> (Dest)           <span class="comment">/* load Dest address into edi */</span>
<a name="l01528"></a>01528                 :
<a name="l01529"></a>01529                 : <span class="stringliteral">&quot;memory&quot;</span>, <span class="stringliteral">&quot;rax&quot;</span>, <span class="stringliteral">&quot;rbx&quot;</span>
<a name="l01530"></a>01530 <span class="preprocessor">#  endif</span>
<a name="l01531"></a>01531 <span class="preprocessor"></span>                );
<a name="l01532"></a>01532 <span class="preprocessor">#endif</span>
<a name="l01533"></a>01533 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l01534"></a>01534 <span class="preprocessor">#else</span>
<a name="l01535"></a>01535 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l01536"></a>01536 <span class="preprocessor">#endif</span>
<a name="l01537"></a>01537 <span class="preprocessor"></span>}
<a name="l01538"></a>01538 
<a name="l01549"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a2944f525acc587ca8d701fbdf1a49c36">01549</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a0ea22f01c6a4724bac307da3e5355f58" title="Filter using Div: D = S1 / S2.">SDL_imageFilterDiv</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src2, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
<a name="l01550"></a>01550 {
<a name="l01551"></a>01551         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l01552"></a>01552         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *cursrc2, *curdst;
<a name="l01553"></a>01553 
<a name="l01554"></a>01554         <span class="comment">/* Validate input parameters */</span>
<a name="l01555"></a>01555         <span class="keywordflow">if</span> ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL))
<a name="l01556"></a>01556                 <span class="keywordflow">return</span>(-1);
<a name="l01557"></a>01557         <span class="keywordflow">if</span> (length == 0)
<a name="l01558"></a>01558                 <span class="keywordflow">return</span>(0);
<a name="l01559"></a>01559 
<a name="l01560"></a>01560         <span class="keywordflow">if</span> (<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) {
<a name="l01561"></a>01561                 <span class="keywordflow">if</span> (length &gt; 0) {
<a name="l01562"></a>01562                         <span class="comment">/* Call ASM routine */</span>
<a name="l01563"></a>01563                         SDL_imageFilterDivASM(Src1, Src2, Dest, length);
<a name="l01564"></a>01564 
<a name="l01565"></a>01565                         <span class="comment">/* Never unaligned bytes - we are done */</span>
<a name="l01566"></a>01566                         <span class="keywordflow">return</span> (0);
<a name="l01567"></a>01567                 } <span class="keywordflow">else</span> {
<a name="l01568"></a>01568                         <span class="keywordflow">return</span> (-1);
<a name="l01569"></a>01569                 }
<a name="l01570"></a>01570         } 
<a name="l01571"></a>01571         
<a name="l01572"></a>01572         <span class="comment">/* Setup to process whole image */</span>
<a name="l01573"></a>01573         istart = 0;
<a name="l01574"></a>01574         cursrc1 = Src1;
<a name="l01575"></a>01575         cursrc2 = Src2;
<a name="l01576"></a>01576         curdst = Dest;
<a name="l01577"></a>01577 
<a name="l01578"></a>01578         <span class="comment">/* C routine to process image */</span>
<a name="l01579"></a>01579         <span class="comment">/* for (i = istart; i &lt; length; i++) { */</span>
<a name="l01580"></a>01580         <span class="comment">/*      if (*cursrc2 == 0) { */</span>
<a name="l01581"></a>01581         <span class="comment">/*              *curdst = 255; */</span>
<a name="l01582"></a>01582         <span class="comment">/*      } else { */</span>
<a name="l01583"></a>01583         <span class="comment">/*              result = (int) *cursrc1 / (int) *cursrc2; */</span>
<a name="l01584"></a>01584         <span class="comment">/*              *curdst = (unsigned char) result; */</span>
<a name="l01585"></a>01585         <span class="comment">/*      } */</span>
<a name="l01586"></a>01586         <span class="comment">/*      /\* Advance pointers *\/ */</span>
<a name="l01587"></a>01587         <span class="comment">/*      cursrc1++; */</span>
<a name="l01588"></a>01588         <span class="comment">/*      cursrc2++; */</span>
<a name="l01589"></a>01589         <span class="comment">/*      curdst++; */</span>
<a name="l01590"></a>01590         <span class="comment">/* } */</span>
<a name="l01591"></a>01591         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l01592"></a>01592                 <span class="keywordflow">if</span> (*cursrc2 == 0) {
<a name="l01593"></a>01593                         *curdst = 255;
<a name="l01594"></a>01594                 } <span class="keywordflow">else</span> {
<a name="l01595"></a>01595                         *curdst = (int)*cursrc1 / (<span class="keywordtype">int</span>)*cursrc2;  <span class="comment">// (int) for efficiency</span>
<a name="l01596"></a>01596                 }
<a name="l01597"></a>01597                 <span class="comment">/* Advance pointers */</span>
<a name="l01598"></a>01598                 cursrc1++;
<a name="l01599"></a>01599                 cursrc2++;
<a name="l01600"></a>01600                 curdst++;
<a name="l01601"></a>01601         }
<a name="l01602"></a>01602 
<a name="l01603"></a>01603         <span class="keywordflow">return</span> (0);
<a name="l01604"></a>01604 }
<a name="l01605"></a>01605 
<a name="l01606"></a>01606 <span class="comment">/* ------------------------------------------------------------------------------------ */</span>
<a name="l01607"></a>01607 
<a name="l01617"></a>01617 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterBitNegationMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength)
<a name="l01618"></a>01618 {
<a name="l01619"></a>01619 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l01620"></a>01620 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l01621"></a>01621 <span class="preprocessor"></span>        __asm
<a name="l01622"></a>01622         {
<a name="l01623"></a>01623                 pusha
<a name="l01624"></a>01624                         pcmpeqb mm1, mm1        <span class="comment">/* generate all 1&#39;s in mm1 */</span>
<a name="l01625"></a>01625                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l01626"></a>01626                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l01627"></a>01627                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l01628"></a>01628                         shr ecx,  3     <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l01629"></a>01629                         align 16                <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l01630"></a>01630 L91117:
<a name="l01631"></a>01631                 movq mm0, [eax]         <span class="comment">/* load 8 bytes from Src1 into mm1 */</span>
<a name="l01632"></a>01632                 pxor mm0, mm1           <span class="comment">/* negate mm0 by xoring with mm1 */</span>
<a name="l01633"></a>01633                         movq [edi], mm0         <span class="comment">/* store result in Dest */</span>
<a name="l01634"></a>01634                         add eax, 8      <span class="comment">/* increase Src1, Src2 and Dest  */</span>
<a name="l01635"></a>01635                         add edi,  8
<a name="l01636"></a>01636                         dec ecx         <span class="comment">/* decrease loop counter */</span>
<a name="l01637"></a>01637                         jnz L91117              <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l01638"></a>01638                         emms                    <span class="comment">/* exit MMX state */</span>
<a name="l01639"></a>01639                         popa
<a name="l01640"></a>01640         }
<a name="l01641"></a>01641 <span class="preprocessor">#else</span>
<a name="l01642"></a>01642 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l01643"></a>01643         __m64 *mSrc1 = (__m64*)Src1;
<a name="l01644"></a>01644         __m64 *mDest = (__m64*)Dest;
<a name="l01645"></a>01645         __m64 mm1;
<a name="l01646"></a>01646         mm1 = _m_pcmpeqb(mm1, mm1);             <span class="comment">/* generate all 1&#39;s in mm1 */</span>
<a name="l01647"></a>01647         <span class="keywordtype">int</span> i;
<a name="l01648"></a>01648         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l01649"></a>01649                 *mDest = _m_pxor(*mSrc1, mm1);  <span class="comment">/* negate mm0 by xoring with mm1 */</span>
<a name="l01650"></a>01650                 mSrc1++;
<a name="l01651"></a>01651                 mDest++;
<a name="l01652"></a>01652         }
<a name="l01653"></a>01653         _m_empty();                             <span class="comment">/* clean MMX state */</span>
<a name="l01654"></a>01654 
<a name="l01655"></a>01655 <span class="preprocessor">#endif</span>
<a name="l01656"></a>01656 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l01657"></a>01657 <span class="preprocessor">#else</span>
<a name="l01658"></a>01658 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l01659"></a>01659 <span class="preprocessor">#endif</span>
<a name="l01660"></a>01660 <span class="preprocessor"></span>}
<a name="l01661"></a>01661 
<a name="l01671"></a><a class="code" href="_s_d_l2__image_filter_8h.html#ac11af558f478ec72eb2b61e8bdf43225">01671</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#ac3abfaa8ec2e88c3c4893588c5555856" title="Filter using BitNegation: D = !S.">SDL_imageFilterBitNegation</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)
<a name="l01672"></a>01672 {
<a name="l01673"></a>01673         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l01674"></a>01674         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *curdst;
<a name="l01675"></a>01675 
<a name="l01676"></a>01676         <span class="comment">/* Validate input parameters */</span>
<a name="l01677"></a>01677         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l01678"></a>01678                 <span class="keywordflow">return</span>(-1);
<a name="l01679"></a>01679         <span class="keywordflow">if</span> (length == 0)
<a name="l01680"></a>01680                 <span class="keywordflow">return</span>(0);
<a name="l01681"></a>01681 
<a name="l01682"></a>01682         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l01683"></a>01683                 <span class="comment">/* MMX routine */</span>
<a name="l01684"></a>01684                 SDL_imageFilterBitNegationMMX(Src1, Dest, length);
<a name="l01685"></a>01685 
<a name="l01686"></a>01686                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l01687"></a>01687                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l01688"></a>01688                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l01689"></a>01689                         istart = length &amp; 0xfffffff8;
<a name="l01690"></a>01690                         cursrc1 = &amp;Src1[istart];
<a name="l01691"></a>01691                         curdst = &amp;Dest[istart];
<a name="l01692"></a>01692                 } <span class="keywordflow">else</span> {
<a name="l01693"></a>01693                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l01694"></a>01694                         <span class="keywordflow">return</span> (0);
<a name="l01695"></a>01695                 }
<a name="l01696"></a>01696         } <span class="keywordflow">else</span> {
<a name="l01697"></a>01697                 <span class="comment">/* Setup to process whole image */</span>
<a name="l01698"></a>01698                 istart = 0;
<a name="l01699"></a>01699                 cursrc1 = Src1;
<a name="l01700"></a>01700                 curdst = Dest;
<a name="l01701"></a>01701         }
<a name="l01702"></a>01702 
<a name="l01703"></a>01703         <span class="comment">/* C routine to process image */</span>
<a name="l01704"></a>01704         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l01705"></a>01705                 *curdst = ~(*cursrc1);
<a name="l01706"></a>01706                 <span class="comment">/* Advance pointers */</span>
<a name="l01707"></a>01707                 cursrc1++;
<a name="l01708"></a>01708                 curdst++;
<a name="l01709"></a>01709         }
<a name="l01710"></a>01710 
<a name="l01711"></a>01711         <span class="keywordflow">return</span> (0);
<a name="l01712"></a>01712 }
<a name="l01713"></a>01713 
<a name="l01724"></a>01724 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterAddByteMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> C)
<a name="l01725"></a>01725 {
<a name="l01726"></a>01726 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l01727"></a>01727 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l01728"></a>01728 <span class="preprocessor"></span>        __asm
<a name="l01729"></a>01729         {
<a name="l01730"></a>01730                 pusha
<a name="l01731"></a>01731                         <span class="comment">/* ** Duplicate C in 8 bytes of MM1 ** */</span>
<a name="l01732"></a>01732                         mov al, C       <span class="comment">/* load C into AL */</span>
<a name="l01733"></a>01733                         mov ah, al      <span class="comment">/* copy AL into AH */</span>
<a name="l01734"></a>01734                         mov bx, ax      <span class="comment">/* copy AX into BX */</span>
<a name="l01735"></a>01735                         shl eax, 16     <span class="comment">/* shift 2 bytes of EAX left */</span>
<a name="l01736"></a>01736                         mov ax, bx      <span class="comment">/* copy BX into AX */</span>
<a name="l01737"></a>01737                         movd mm1, eax           <span class="comment">/* copy EAX into MM1 */</span>
<a name="l01738"></a>01738                         movd mm2, eax           <span class="comment">/* copy EAX into MM2 */</span>
<a name="l01739"></a>01739                         punpckldq mm1, mm2      <span class="comment">/* fill higher bytes of MM1 with C */</span>
<a name="l01740"></a>01740                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l01741"></a>01741                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l01742"></a>01742                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l01743"></a>01743                         shr ecx,  3     <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l01744"></a>01744                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l01745"></a>01745 L1021:
<a name="l01746"></a>01746                 movq mm0, [eax]         <span class="comment">/* load 8 bytes from Src1 into MM0 */</span>
<a name="l01747"></a>01747                 paddusb mm0,  mm1       <span class="comment">/* MM0=SrcDest+C (add 8 bytes with saturation) */</span>
<a name="l01748"></a>01748                         movq [edi], mm0         <span class="comment">/* store result in Dest */</span>
<a name="l01749"></a>01749                         add eax, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l01750"></a>01750                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l01751"></a>01751                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l01752"></a>01752                         jnz             L1021           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l01753"></a>01753                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l01754"></a>01754                         popa
<a name="l01755"></a>01755         }
<a name="l01756"></a>01756 <span class="preprocessor">#else</span>
<a name="l01757"></a>01757 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l01758"></a>01758         __m64 *mSrc1 = (__m64*)Src1;
<a name="l01759"></a>01759         __m64 *mDest = (__m64*)Dest;
<a name="l01760"></a>01760         <span class="comment">/* Duplicate C in 8 bytes of MM1 */</span>
<a name="l01761"></a>01761         <span class="keywordtype">int</span> i;
<a name="l01762"></a>01762         memset(&amp;i, C, 4);
<a name="l01763"></a>01763         __m64 mm1 = _m_from_int(i);
<a name="l01764"></a>01764         __m64 mm2 = _m_from_int(i);
<a name="l01765"></a>01765         mm1 = _m_punpckldq(mm1, mm2);                   <span class="comment">/* fill higher bytes of MM1 with C */</span>
<a name="l01766"></a>01766         <span class="comment">//__m64 mm1 = _m_from_int64(lli); // x86_64 only</span>
<a name="l01767"></a>01767         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l01768"></a>01768                 *mDest = _m_paddusb(*mSrc1, mm1);       <span class="comment">/* Src1+C (add 8 bytes with saturation) */</span>
<a name="l01769"></a>01769                 mSrc1++;
<a name="l01770"></a>01770                 mDest++;
<a name="l01771"></a>01771         }
<a name="l01772"></a>01772         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l01773"></a>01773 <span class="preprocessor">#endif</span>
<a name="l01774"></a>01774 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l01775"></a>01775 <span class="preprocessor">#else</span>
<a name="l01776"></a>01776 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l01777"></a>01777 <span class="preprocessor">#endif</span>
<a name="l01778"></a>01778 <span class="preprocessor"></span>}
<a name="l01779"></a>01779 
<a name="l01791"></a><a class="code" href="_s_d_l2__image_filter_8h.html#ad00178c9482a9959023a6bec03c8dba5">01791</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a812cb307cb60ef31f1ffe81a9eee6bb1" title="Filter using AddByte: D = saturation255(S + C)">SDL_imageFilterAddByte</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> C)
<a name="l01792"></a>01792 {
<a name="l01793"></a>01793         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l01794"></a>01794         <span class="keywordtype">int</span> iC;
<a name="l01795"></a>01795         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *curdest;
<a name="l01796"></a>01796         <span class="keywordtype">int</span> result;
<a name="l01797"></a>01797 
<a name="l01798"></a>01798         <span class="comment">/* Validate input parameters */</span>
<a name="l01799"></a>01799         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l01800"></a>01800                 <span class="keywordflow">return</span>(-1);
<a name="l01801"></a>01801         <span class="keywordflow">if</span> (length == 0)
<a name="l01802"></a>01802                 <span class="keywordflow">return</span>(0);
<a name="l01803"></a>01803 
<a name="l01804"></a>01804         <span class="comment">/* Special case: C==0 */</span>
<a name="l01805"></a>01805         <span class="keywordflow">if</span> (C == 0) {
<a name="l01806"></a>01806                 memcpy(Src1, Dest, length);
<a name="l01807"></a>01807                 <span class="keywordflow">return</span> (0); 
<a name="l01808"></a>01808         }
<a name="l01809"></a>01809 
<a name="l01810"></a>01810         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l01811"></a>01811 
<a name="l01812"></a>01812                 <span class="comment">/* MMX routine */</span>
<a name="l01813"></a>01813                 SDL_imageFilterAddByteMMX(Src1, Dest, length, C);
<a name="l01814"></a>01814 
<a name="l01815"></a>01815                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l01816"></a>01816                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l01817"></a>01817                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l01818"></a>01818                         istart = length &amp; 0xfffffff8;
<a name="l01819"></a>01819                         cursrc1 = &amp;Src1[istart];
<a name="l01820"></a>01820                         curdest = &amp;Dest[istart];
<a name="l01821"></a>01821                 } <span class="keywordflow">else</span> {
<a name="l01822"></a>01822                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l01823"></a>01823                         <span class="keywordflow">return</span> (0);
<a name="l01824"></a>01824                 }
<a name="l01825"></a>01825         } <span class="keywordflow">else</span> {
<a name="l01826"></a>01826                 <span class="comment">/* Setup to process whole image */</span>
<a name="l01827"></a>01827                 istart = 0;
<a name="l01828"></a>01828                 cursrc1 = Src1;
<a name="l01829"></a>01829                 curdest = Dest;
<a name="l01830"></a>01830         }
<a name="l01831"></a>01831 
<a name="l01832"></a>01832         <span class="comment">/* C routine to process image */</span>
<a name="l01833"></a>01833         iC = (int) C;
<a name="l01834"></a>01834         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l01835"></a>01835                 result = (int) *cursrc1 + iC;
<a name="l01836"></a>01836                 <span class="keywordflow">if</span> (result &gt; 255)
<a name="l01837"></a>01837                         result = 255;
<a name="l01838"></a>01838                 *curdest = (<span class="keywordtype">unsigned</span> char) result;
<a name="l01839"></a>01839                 <span class="comment">/* Advance pointers */</span>
<a name="l01840"></a>01840                 cursrc1++;
<a name="l01841"></a>01841                 curdest++;
<a name="l01842"></a>01842         }
<a name="l01843"></a>01843         <span class="keywordflow">return</span> (0);
<a name="l01844"></a>01844 }
<a name="l01845"></a>01845 
<a name="l01857"></a>01857 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterAddUintMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> C, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> D)
<a name="l01858"></a>01858 {
<a name="l01859"></a>01859 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l01860"></a>01860 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l01861"></a>01861 <span class="preprocessor"></span>        __asm
<a name="l01862"></a>01862         {
<a name="l01863"></a>01863                 pusha
<a name="l01864"></a>01864                         <span class="comment">/* ** Duplicate (int)C in 8 bytes of MM1 ** */</span>
<a name="l01865"></a>01865                         mov eax, C      <span class="comment">/* load C into EAX */</span>
<a name="l01866"></a>01866                         movd mm1, eax           <span class="comment">/* copy EAX into MM1 */</span>
<a name="l01867"></a>01867                         mov eax, D      <span class="comment">/* load D into EAX */</span>
<a name="l01868"></a>01868                         movd mm2, eax           <span class="comment">/* copy EAX into MM2 */</span>
<a name="l01869"></a>01869                         punpckldq mm1, mm2      <span class="comment">/* fill higher bytes of MM1 with C */</span>
<a name="l01870"></a>01870                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l01871"></a>01871                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l01872"></a>01872                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l01873"></a>01873                         shr ecx,  3     <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l01874"></a>01874                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l01875"></a>01875 L11023:
<a name="l01876"></a>01876                 movq mm0, [eax]         <span class="comment">/* load 8 bytes from SrcDest into MM0 */</span>
<a name="l01877"></a>01877                 paddusb mm0,  mm1       <span class="comment">/* MM0=SrcDest+C (add 8 bytes with saturation) */</span>
<a name="l01878"></a>01878                         movq [edi],  mm0        <span class="comment">/* store result in SrcDest */</span>
<a name="l01879"></a>01879                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l01880"></a>01880                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l01881"></a>01881                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l01882"></a>01882                         jnz             L11023          <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l01883"></a>01883                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l01884"></a>01884                         popa
<a name="l01885"></a>01885         }
<a name="l01886"></a>01886 <span class="preprocessor">#else</span>
<a name="l01887"></a>01887 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l01888"></a>01888         __m64 *mSrc1 = (__m64*)Src1;
<a name="l01889"></a>01889         __m64 *mDest = (__m64*)Dest;
<a name="l01890"></a>01890         <span class="comment">/* Duplicate (int)C in 8 bytes of MM1 */</span>
<a name="l01891"></a>01891         __m64 mm1 = _m_from_int(C);
<a name="l01892"></a>01892         __m64 mm2 = _m_from_int(C);
<a name="l01893"></a>01893         mm1 = _m_punpckldq(mm1, mm2);                   <span class="comment">/* fill higher bytes of MM1 with C */</span>
<a name="l01894"></a>01894         <span class="comment">//__m64 mm1 = _m_from_int64(lli); // x86_64 only</span>
<a name="l01895"></a>01895         <span class="keywordtype">int</span> i;
<a name="l01896"></a>01896         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l01897"></a>01897                 *mDest = _m_paddusb(*mSrc1, mm1);       <span class="comment">/* Src1+C (add 8 bytes with saturation) */</span>
<a name="l01898"></a>01898                 mSrc1++;
<a name="l01899"></a>01899                 mDest++;
<a name="l01900"></a>01900         }
<a name="l01901"></a>01901         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l01902"></a>01902 <span class="preprocessor">#endif</span>
<a name="l01903"></a>01903 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l01904"></a>01904 <span class="preprocessor">#else</span>
<a name="l01905"></a>01905 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l01906"></a>01906 <span class="preprocessor">#endif</span>
<a name="l01907"></a>01907 <span class="preprocessor"></span>}
<a name="l01908"></a>01908 
<a name="l01919"></a><a class="code" href="_s_d_l2__image_filter_8h.html#ab7d7f266f047a63755a2341cdfe018e9">01919</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a660543426c47dfec39a349eb3b8f905b" title="Filter using AddUint: D = saturation255((S[i] + Cs[i % 4]), Cs=Swap32((uint)C)">SDL_imageFilterAddUint</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> C)
<a name="l01920"></a>01920 {
<a name="l01921"></a>01921         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, j, istart, D;
<a name="l01922"></a>01922         <span class="keywordtype">int</span> iC[4];
<a name="l01923"></a>01923         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1;
<a name="l01924"></a>01924         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *curdest;
<a name="l01925"></a>01925         <span class="keywordtype">int</span> result;
<a name="l01926"></a>01926 
<a name="l01927"></a>01927         <span class="comment">/* Validate input parameters */</span>
<a name="l01928"></a>01928         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l01929"></a>01929                 <span class="keywordflow">return</span>(-1);
<a name="l01930"></a>01930         <span class="keywordflow">if</span> (length == 0)
<a name="l01931"></a>01931                 <span class="keywordflow">return</span>(0);
<a name="l01932"></a>01932 
<a name="l01933"></a>01933         <span class="comment">/* Special case: C==0 */</span>
<a name="l01934"></a>01934         <span class="keywordflow">if</span> (C == 0) {
<a name="l01935"></a>01935                 memcpy(Src1, Dest, length);
<a name="l01936"></a>01936                 <span class="keywordflow">return</span> (0); 
<a name="l01937"></a>01937         }
<a name="l01938"></a>01938 
<a name="l01939"></a>01939         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l01940"></a>01940 
<a name="l01941"></a>01941                 <span class="comment">/* MMX routine */</span>
<a name="l01942"></a>01942                 D=<a class="code" href="_s_d_l2__image_filter_8c.html#a700fb30611761c46a674a45cc28ff561" title="Swaps the byte order in a 32bit integer (LSB becomes MSB, etc.).">SWAP_32</a>(C);
<a name="l01943"></a>01943                 SDL_imageFilterAddUintMMX(Src1, Dest, length, C, D);
<a name="l01944"></a>01944 
<a name="l01945"></a>01945                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l01946"></a>01946                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l01947"></a>01947                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l01948"></a>01948                         istart = length &amp; 0xfffffff8;
<a name="l01949"></a>01949                         cursrc1 = &amp;Src1[istart];
<a name="l01950"></a>01950                         curdest = &amp;Dest[istart];
<a name="l01951"></a>01951                 } <span class="keywordflow">else</span> {
<a name="l01952"></a>01952                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l01953"></a>01953                         <span class="keywordflow">return</span> (0);
<a name="l01954"></a>01954                 }
<a name="l01955"></a>01955         } <span class="keywordflow">else</span> {
<a name="l01956"></a>01956                 <span class="comment">/* Setup to process whole image */</span>
<a name="l01957"></a>01957                 istart = 0;
<a name="l01958"></a>01958                 cursrc1 = Src1;
<a name="l01959"></a>01959                 curdest = Dest;
<a name="l01960"></a>01960         }
<a name="l01961"></a>01961 
<a name="l01962"></a>01962         <span class="comment">/* C routine to process bytes */</span>
<a name="l01963"></a>01963         iC[3] = (int) ((C &gt;&gt; 24) &amp; 0xff);
<a name="l01964"></a>01964         iC[2] = (int) ((C &gt;&gt; 16) &amp; 0xff);
<a name="l01965"></a>01965         iC[1] = (int) ((C &gt;&gt;  8) &amp; 0xff);
<a name="l01966"></a>01966         iC[0] = (int) ((C &gt;&gt;  0) &amp; 0xff);
<a name="l01967"></a>01967         <span class="keywordflow">for</span> (i = istart; i &lt; length; i += 4) {
<a name="l01968"></a>01968                 <span class="keywordflow">for</span> (j = 0; j &lt; 4; j++) {
<a name="l01969"></a>01969                         <span class="keywordflow">if</span> ((i+j)&lt;length) {
<a name="l01970"></a>01970                                 result = (int) *cursrc1 + iC[j];
<a name="l01971"></a>01971                                 <span class="keywordflow">if</span> (result &gt; 255) result = 255;
<a name="l01972"></a>01972                                 *curdest = (<span class="keywordtype">unsigned</span> char) result;
<a name="l01973"></a>01973                                 <span class="comment">/* Advance pointers */</span>
<a name="l01974"></a>01974                                 cursrc1++;
<a name="l01975"></a>01975                                 curdest++;
<a name="l01976"></a>01976                         }
<a name="l01977"></a>01977                 }
<a name="l01978"></a>01978         }
<a name="l01979"></a>01979         <span class="keywordflow">return</span> (0);
<a name="l01980"></a>01980 }
<a name="l01981"></a>01981 
<a name="l01993"></a>01993 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterAddByteToHalfMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> C,
<a name="l01994"></a>01994                                                                         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Mask)
<a name="l01995"></a>01995 {
<a name="l01996"></a>01996 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l01997"></a>01997 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l01998"></a>01998 <span class="preprocessor"></span>        __asm
<a name="l01999"></a>01999         {
<a name="l02000"></a>02000                 pusha
<a name="l02001"></a>02001                         <span class="comment">/* ** Duplicate C in 8 bytes of MM1 ** */</span>
<a name="l02002"></a>02002                         mov al, C       <span class="comment">/* load C into AL */</span>
<a name="l02003"></a>02003                         mov ah, al      <span class="comment">/* copy AL into AH */</span>
<a name="l02004"></a>02004                         mov bx, ax      <span class="comment">/* copy AX into BX */</span>
<a name="l02005"></a>02005                         shl eax, 16     <span class="comment">/* shift 2 bytes of EAX left */</span>
<a name="l02006"></a>02006                         mov ax, bx      <span class="comment">/* copy BX into AX */</span>
<a name="l02007"></a>02007                         movd mm1, eax           <span class="comment">/* copy EAX into MM1 */</span>
<a name="l02008"></a>02008                         movd mm2, eax           <span class="comment">/* copy EAX into MM2 */</span>
<a name="l02009"></a>02009                         punpckldq mm1, mm2      <span class="comment">/* fill higher bytes of MM1 with C */</span>
<a name="l02010"></a>02010                         mov edx, Mask           <span class="comment">/* load Mask address into edx */</span>
<a name="l02011"></a>02011                         movq mm0, [edx]         <span class="comment">/* load Mask into mm0 */</span>
<a name="l02012"></a>02012                 mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l02013"></a>02013                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l02014"></a>02014                         mov ecx,  SrcLength     <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l02015"></a>02015                         shr ecx,  3     <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l02016"></a>02016                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l02017"></a>02017 L1022:
<a name="l02018"></a>02018                 movq mm2, [eax]         <span class="comment">/* load 8 bytes from Src1 into MM2 */</span>
<a name="l02019"></a>02019                 psrlw mm2, 1    <span class="comment">/* shift 4 WORDS of MM2 1 bit to the right */</span>
<a name="l02020"></a>02020                         pand mm2, mm0        <span class="comment">// apply Mask to 8 BYTES of MM2 */</span>
<a name="l02021"></a>02021                         paddusb mm2,  mm1       <span class="comment">/* MM2=SrcDest+C (add 8 bytes with saturation) */</span>
<a name="l02022"></a>02022                         movq [edi], mm2         <span class="comment">/* store result in Dest */</span>
<a name="l02023"></a>02023                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l02024"></a>02024                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l02025"></a>02025                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l02026"></a>02026                         jnz             L1022           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l02027"></a>02027                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l02028"></a>02028                         popa
<a name="l02029"></a>02029         }
<a name="l02030"></a>02030 <span class="preprocessor">#else</span>
<a name="l02031"></a>02031 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l02032"></a>02032         __m64 *mSrc1 = (__m64*)Src1;
<a name="l02033"></a>02033         __m64 *mDest = (__m64*)Dest;
<a name="l02034"></a>02034         __m64 *mMask = (__m64*)Mask;
<a name="l02035"></a>02035         <span class="comment">/* Duplicate C in 8 bytes of MM1 */</span>
<a name="l02036"></a>02036         <span class="keywordtype">int</span> i;
<a name="l02037"></a>02037         memset(&amp;i, C, 4);
<a name="l02038"></a>02038         __m64 mm1 = _m_from_int(i);
<a name="l02039"></a>02039         __m64 mm2 = _m_from_int(i);
<a name="l02040"></a>02040         mm1 = _m_punpckldq(mm1, mm2);                   <span class="comment">/* fill higher bytes of MM1 with C */</span>
<a name="l02041"></a>02041         <span class="comment">//__m64 mm1 = _m_from_int64(lli); // x86_64 only</span>
<a name="l02042"></a>02042         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l02043"></a>02043                 __m64 mm2 = _m_psrlwi(*mSrc1, 1);       <span class="comment">/* shift 4 WORDS of MM2 1 bit to the right */</span>
<a name="l02044"></a>02044                 mm2 = _m_pand(mm2, *mMask);             <span class="comment">/* apply Mask to 8 BYTES of MM2 */</span>
<a name="l02045"></a>02045                                                         <span class="comment">/* byte     0x0f, 0xdb, 0xd0 */</span>
<a name="l02046"></a>02046                 *mDest = _m_paddusb(mm1, mm2);          <span class="comment">/* Src1+C (add 8 bytes with saturation) */</span>
<a name="l02047"></a>02047                 mSrc1++;
<a name="l02048"></a>02048                 mDest++;
<a name="l02049"></a>02049         }
<a name="l02050"></a>02050         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l02051"></a>02051 <span class="preprocessor">#endif</span>
<a name="l02052"></a>02052 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l02053"></a>02053 <span class="preprocessor">#else</span>
<a name="l02054"></a>02054 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l02055"></a>02055 <span class="preprocessor">#endif</span>
<a name="l02056"></a>02056 <span class="preprocessor"></span>}
<a name="l02057"></a>02057 
<a name="l02068"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a0da2fbdf760a1e248200763e83917c33">02068</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#ab82db97d129c8cfc36780bcdc6286fcc" title="Filter using AddByteToHalf: D = saturation255(S/2 + C)">SDL_imageFilterAddByteToHalf</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> C)
<a name="l02069"></a>02069 {
<a name="l02070"></a>02070         <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Mask[8] = { 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F };
<a name="l02071"></a>02071         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l02072"></a>02072         <span class="keywordtype">int</span> iC;
<a name="l02073"></a>02073         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1;
<a name="l02074"></a>02074         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *curdest;
<a name="l02075"></a>02075         <span class="keywordtype">int</span> result;
<a name="l02076"></a>02076 
<a name="l02077"></a>02077         <span class="comment">/* Validate input parameters */</span>
<a name="l02078"></a>02078         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l02079"></a>02079                 <span class="keywordflow">return</span>(-1);
<a name="l02080"></a>02080         <span class="keywordflow">if</span> (length == 0)
<a name="l02081"></a>02081                 <span class="keywordflow">return</span>(0);
<a name="l02082"></a>02082 
<a name="l02083"></a>02083         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l02084"></a>02084 
<a name="l02085"></a>02085                 <span class="comment">/* MMX routine */</span>
<a name="l02086"></a>02086                 SDL_imageFilterAddByteToHalfMMX(Src1, Dest, length, C, Mask);
<a name="l02087"></a>02087 
<a name="l02088"></a>02088                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l02089"></a>02089                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l02090"></a>02090                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l02091"></a>02091                         istart = length &amp; 0xfffffff8;
<a name="l02092"></a>02092                         cursrc1 = &amp;Src1[istart];
<a name="l02093"></a>02093                         curdest = &amp;Dest[istart];
<a name="l02094"></a>02094                 } <span class="keywordflow">else</span> {
<a name="l02095"></a>02095                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l02096"></a>02096                         <span class="keywordflow">return</span> (0);
<a name="l02097"></a>02097                 }
<a name="l02098"></a>02098         } <span class="keywordflow">else</span> {
<a name="l02099"></a>02099                 <span class="comment">/* Setup to process whole image */</span>
<a name="l02100"></a>02100                 istart = 0;
<a name="l02101"></a>02101                 cursrc1 = Src1;
<a name="l02102"></a>02102                 curdest = Dest;
<a name="l02103"></a>02103         }
<a name="l02104"></a>02104 
<a name="l02105"></a>02105         <span class="comment">/* C routine to process image */</span>
<a name="l02106"></a>02106         iC = (int) C;
<a name="l02107"></a>02107         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l02108"></a>02108                 result = (int) (*cursrc1 / 2) + iC;
<a name="l02109"></a>02109                 <span class="keywordflow">if</span> (result &gt; 255)
<a name="l02110"></a>02110                         result = 255;
<a name="l02111"></a>02111                 *curdest = (<span class="keywordtype">unsigned</span> char) result;
<a name="l02112"></a>02112                 <span class="comment">/* Advance pointers */</span>
<a name="l02113"></a>02113                 cursrc1++;
<a name="l02114"></a>02114                 curdest++;
<a name="l02115"></a>02115         }
<a name="l02116"></a>02116 
<a name="l02117"></a>02117         <span class="keywordflow">return</span> (0);
<a name="l02118"></a>02118 }
<a name="l02119"></a>02119 
<a name="l02130"></a><a class="code" href="_s_d_l2__image_filter_8c.html#a657e128016cc448778007d8b6475dd65">02130</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a657e128016cc448778007d8b6475dd65" title="Internal MMX Filter using SubByte: D = saturation0(S - C)">SDL_imageFilterSubByteMMX</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> C)
<a name="l02131"></a>02131 {
<a name="l02132"></a>02132 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l02133"></a>02133 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l02134"></a>02134 <span class="preprocessor"></span>        __asm
<a name="l02135"></a>02135         {
<a name="l02136"></a>02136                 pusha
<a name="l02137"></a>02137                         <span class="comment">/* ** Duplicate C in 8 bytes of MM1 ** */</span>
<a name="l02138"></a>02138                         mov al, C       <span class="comment">/* load C into AL */</span>
<a name="l02139"></a>02139                         mov ah, al      <span class="comment">/* copy AL into AH */</span>
<a name="l02140"></a>02140                         mov bx, ax      <span class="comment">/* copy AX into BX */</span>
<a name="l02141"></a>02141                         shl eax, 16     <span class="comment">/* shift 2 bytes of EAX left */</span>
<a name="l02142"></a>02142                         mov ax, bx      <span class="comment">/* copy BX into AX */</span>
<a name="l02143"></a>02143                         movd mm1, eax           <span class="comment">/* copy EAX into MM1 */</span>
<a name="l02144"></a>02144                         movd mm2, eax           <span class="comment">/* copy EAX into MM2 */</span>
<a name="l02145"></a>02145                         punpckldq mm1, mm2      <span class="comment">/* fill higher bytes of MM1 with C */</span>
<a name="l02146"></a>02146                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l02147"></a>02147                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l02148"></a>02148                         mov ecx,  SrcLength     <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l02149"></a>02149                         shr ecx,  3     <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l02150"></a>02150                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l02151"></a>02151 L1023:
<a name="l02152"></a>02152                 movq mm0, [eax]         <span class="comment">/* load 8 bytes from SrcDest into MM0 */</span>
<a name="l02153"></a>02153                 psubusb mm0,  mm1       <span class="comment">/* MM0=SrcDest-C (sub 8 bytes with saturation) */</span>
<a name="l02154"></a>02154                         movq [edi], mm0         <span class="comment">/* store result in SrcDest */</span>
<a name="l02155"></a>02155                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l02156"></a>02156                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l02157"></a>02157                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l02158"></a>02158                         jnz             L1023           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l02159"></a>02159                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l02160"></a>02160                         popa
<a name="l02161"></a>02161         }
<a name="l02162"></a>02162 <span class="preprocessor">#else</span>
<a name="l02163"></a>02163 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l02164"></a>02164         __m64 *mSrc1 = (__m64*)Src1;
<a name="l02165"></a>02165         __m64 *mDest = (__m64*)Dest;
<a name="l02166"></a>02166         <span class="comment">/* Duplicate C in 8 bytes of MM1 */</span>
<a name="l02167"></a>02167         <span class="keywordtype">int</span> i;
<a name="l02168"></a>02168         memset(&amp;i, C, 4);
<a name="l02169"></a>02169         __m64 mm1 = _m_from_int(i);
<a name="l02170"></a>02170         __m64 mm2 = _m_from_int(i);
<a name="l02171"></a>02171         mm1 = _m_punpckldq(mm1, mm2);                   <span class="comment">/* fill higher bytes of MM1 with C */</span>
<a name="l02172"></a>02172         <span class="comment">//__m64 mm1 = _m_from_int64(lli); // x86_64 only</span>
<a name="l02173"></a>02173         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l02174"></a>02174                 *mDest = _m_psubusb(*mSrc1, mm1);       <span class="comment">/* Src1-C (sub 8 bytes with saturation) */</span>
<a name="l02175"></a>02175                 mSrc1++;
<a name="l02176"></a>02176                 mDest++;
<a name="l02177"></a>02177         }
<a name="l02178"></a>02178         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l02179"></a>02179 <span class="preprocessor">#endif</span>
<a name="l02180"></a>02180 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l02181"></a>02181 <span class="preprocessor">#else</span>
<a name="l02182"></a>02182 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l02183"></a>02183 <span class="preprocessor">#endif</span>
<a name="l02184"></a>02184 <span class="preprocessor"></span>}
<a name="l02185"></a>02185 
<a name="l02196"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a5899423c538fa35660ded0f5945c014f">02196</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a387fb6f0d48cc5d08f37f7f9b92d14b2" title="Filter using SubByte: D = saturation0(S - C)">SDL_imageFilterSubByte</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> C)
<a name="l02197"></a>02197 {
<a name="l02198"></a>02198         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l02199"></a>02199         <span class="keywordtype">int</span> iC;
<a name="l02200"></a>02200         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1;
<a name="l02201"></a>02201         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *curdest;
<a name="l02202"></a>02202         <span class="keywordtype">int</span> result;
<a name="l02203"></a>02203 
<a name="l02204"></a>02204         <span class="comment">/* Validate input parameters */</span>
<a name="l02205"></a>02205         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l02206"></a>02206                 <span class="keywordflow">return</span>(-1);
<a name="l02207"></a>02207         <span class="keywordflow">if</span> (length == 0)
<a name="l02208"></a>02208                 <span class="keywordflow">return</span>(0);
<a name="l02209"></a>02209 
<a name="l02210"></a>02210         <span class="comment">/* Special case: C==0 */</span>
<a name="l02211"></a>02211         <span class="keywordflow">if</span> (C == 0) {
<a name="l02212"></a>02212                 memcpy(Src1, Dest, length);
<a name="l02213"></a>02213                 <span class="keywordflow">return</span> (0); 
<a name="l02214"></a>02214         }
<a name="l02215"></a>02215 
<a name="l02216"></a>02216         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l02217"></a>02217 
<a name="l02218"></a>02218                 <span class="comment">/* MMX routine */</span>
<a name="l02219"></a>02219                 <a class="code" href="_s_d_l2__image_filter_8c.html#a657e128016cc448778007d8b6475dd65" title="Internal MMX Filter using SubByte: D = saturation0(S - C)">SDL_imageFilterSubByteMMX</a>(Src1, Dest, length, C);
<a name="l02220"></a>02220 
<a name="l02221"></a>02221                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l02222"></a>02222                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l02223"></a>02223                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l02224"></a>02224                         istart = length &amp; 0xfffffff8;
<a name="l02225"></a>02225                         cursrc1 = &amp;Src1[istart];
<a name="l02226"></a>02226                         curdest = &amp;Dest[istart];
<a name="l02227"></a>02227                 } <span class="keywordflow">else</span> {
<a name="l02228"></a>02228                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l02229"></a>02229                         <span class="keywordflow">return</span> (0);
<a name="l02230"></a>02230                 }
<a name="l02231"></a>02231         } <span class="keywordflow">else</span> {
<a name="l02232"></a>02232                 <span class="comment">/* Setup to process whole image */</span>
<a name="l02233"></a>02233                 istart = 0;
<a name="l02234"></a>02234                 cursrc1 = Src1;
<a name="l02235"></a>02235                 curdest = Dest;
<a name="l02236"></a>02236         }
<a name="l02237"></a>02237 
<a name="l02238"></a>02238         <span class="comment">/* C routine to process image */</span>
<a name="l02239"></a>02239         iC = (int) C;
<a name="l02240"></a>02240         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l02241"></a>02241                 result = (int) *cursrc1 - iC;
<a name="l02242"></a>02242                 <span class="keywordflow">if</span> (result &lt; 0)
<a name="l02243"></a>02243                         result = 0;
<a name="l02244"></a>02244                 *curdest = (<span class="keywordtype">unsigned</span> char) result;
<a name="l02245"></a>02245                 <span class="comment">/* Advance pointers */</span>
<a name="l02246"></a>02246                 cursrc1++;
<a name="l02247"></a>02247                 curdest++;
<a name="l02248"></a>02248         }
<a name="l02249"></a>02249         <span class="keywordflow">return</span> (0);
<a name="l02250"></a>02250 }
<a name="l02251"></a>02251 
<a name="l02263"></a>02263 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterSubUintMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> C, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> D)
<a name="l02264"></a>02264 {
<a name="l02265"></a>02265 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l02266"></a>02266 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l02267"></a>02267 <span class="preprocessor"></span>        __asm
<a name="l02268"></a>02268         {
<a name="l02269"></a>02269                 pusha
<a name="l02270"></a>02270                         <span class="comment">/* ** Duplicate (int)C in 8 bytes of MM1 ** */</span>
<a name="l02271"></a>02271                         mov eax, C      <span class="comment">/* load C into EAX */</span>
<a name="l02272"></a>02272                         movd mm1, eax           <span class="comment">/* copy EAX into MM1 */</span>
<a name="l02273"></a>02273                         mov eax, D      <span class="comment">/* load D into EAX */</span>
<a name="l02274"></a>02274                         movd mm2, eax           <span class="comment">/* copy EAX into MM2 */</span>
<a name="l02275"></a>02275                         punpckldq mm1, mm2      <span class="comment">/* fill higher bytes of MM1 with C */</span>
<a name="l02276"></a>02276                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l02277"></a>02277                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l02278"></a>02278                         mov ecx,  SrcLength     <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l02279"></a>02279                         shr ecx,  3     <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l02280"></a>02280                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l02281"></a>02281 L11024:
<a name="l02282"></a>02282                 movq mm0, [eax]         <span class="comment">/* load 8 bytes from SrcDest into MM0 */</span>
<a name="l02283"></a>02283                 psubusb mm0, mm1        <span class="comment">/* MM0=SrcDest-C (sub 8 bytes with saturation) */</span>
<a name="l02284"></a>02284                         movq [edi], mm0         <span class="comment">/* store result in SrcDest */</span>
<a name="l02285"></a>02285                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l02286"></a>02286                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l02287"></a>02287                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l02288"></a>02288                         jnz             L11024          <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l02289"></a>02289                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l02290"></a>02290                         popa
<a name="l02291"></a>02291         }
<a name="l02292"></a>02292 <span class="preprocessor">#else</span>
<a name="l02293"></a>02293 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l02294"></a>02294         __m64 *mSrc1 = (__m64*)Src1;
<a name="l02295"></a>02295         __m64 *mDest = (__m64*)Dest;
<a name="l02296"></a>02296         <span class="comment">/* Duplicate (int)C in 8 bytes of MM1 */</span>
<a name="l02297"></a>02297         __m64 mm1 = _m_from_int(C);
<a name="l02298"></a>02298         __m64 mm2 = _m_from_int(C);
<a name="l02299"></a>02299         mm1 = _m_punpckldq(mm1, mm2);                   <span class="comment">/* fill higher bytes of MM1 with C */</span>
<a name="l02300"></a>02300         <span class="comment">//__m64 mm1 = _m_from_int64(lli); // x86_64 only</span>
<a name="l02301"></a>02301         <span class="keywordtype">int</span> i;
<a name="l02302"></a>02302         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l02303"></a>02303                 *mDest = _m_psubusb(*mSrc1, mm1);       <span class="comment">/* Src1-C (sub 8 bytes with saturation) */</span>
<a name="l02304"></a>02304                 mSrc1++;
<a name="l02305"></a>02305                 mDest++;
<a name="l02306"></a>02306         }
<a name="l02307"></a>02307         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l02308"></a>02308 <span class="preprocessor">#endif</span>
<a name="l02309"></a>02309 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l02310"></a>02310 <span class="preprocessor">#else</span>
<a name="l02311"></a>02311 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l02312"></a>02312 <span class="preprocessor">#endif</span>
<a name="l02313"></a>02313 <span class="preprocessor"></span>}
<a name="l02314"></a>02314 
<a name="l02325"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a8532da4511ef9657c8688f66e6309118">02325</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#abb343ef95e22945e1d4d648b2e176e64" title="Filter using SubUint: D = saturation0(S[i] - Cs[i % 4]), Cs=Swap32((uint)C)">SDL_imageFilterSubUint</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> C)
<a name="l02326"></a>02326 {
<a name="l02327"></a>02327         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, j, istart, D;
<a name="l02328"></a>02328         <span class="keywordtype">int</span> iC[4];
<a name="l02329"></a>02329         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1;
<a name="l02330"></a>02330         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *curdest;
<a name="l02331"></a>02331         <span class="keywordtype">int</span> result;
<a name="l02332"></a>02332 
<a name="l02333"></a>02333         <span class="comment">/* Validate input parameters */</span>
<a name="l02334"></a>02334         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l02335"></a>02335                 <span class="keywordflow">return</span>(-1);
<a name="l02336"></a>02336         <span class="keywordflow">if</span> (length == 0)
<a name="l02337"></a>02337                 <span class="keywordflow">return</span>(0);
<a name="l02338"></a>02338 
<a name="l02339"></a>02339     <span class="comment">/* Special case: C==0 */</span>
<a name="l02340"></a>02340         <span class="keywordflow">if</span> (C == 0) {
<a name="l02341"></a>02341                 memcpy(Src1, Dest, length);
<a name="l02342"></a>02342                 <span class="keywordflow">return</span> (0); 
<a name="l02343"></a>02343         }
<a name="l02344"></a>02344 
<a name="l02345"></a>02345         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l02346"></a>02346 
<a name="l02347"></a>02347                 <span class="comment">/* MMX routine */</span>
<a name="l02348"></a>02348                 D=<a class="code" href="_s_d_l2__image_filter_8c.html#a700fb30611761c46a674a45cc28ff561" title="Swaps the byte order in a 32bit integer (LSB becomes MSB, etc.).">SWAP_32</a>(C);
<a name="l02349"></a>02349                 SDL_imageFilterSubUintMMX(Src1, Dest, length, C, D);
<a name="l02350"></a>02350 
<a name="l02351"></a>02351                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l02352"></a>02352                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l02353"></a>02353                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l02354"></a>02354                         istart = length &amp; 0xfffffff8;
<a name="l02355"></a>02355                         cursrc1 = &amp;Src1[istart];
<a name="l02356"></a>02356                         curdest = &amp;Dest[istart];
<a name="l02357"></a>02357                 } <span class="keywordflow">else</span> {
<a name="l02358"></a>02358                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l02359"></a>02359                         <span class="keywordflow">return</span> (0);
<a name="l02360"></a>02360                 }
<a name="l02361"></a>02361         } <span class="keywordflow">else</span> {
<a name="l02362"></a>02362                 <span class="comment">/* Setup to process whole image */</span>
<a name="l02363"></a>02363                 istart = 0;
<a name="l02364"></a>02364                 cursrc1 = Src1;
<a name="l02365"></a>02365                 curdest = Dest;
<a name="l02366"></a>02366         }
<a name="l02367"></a>02367 
<a name="l02368"></a>02368         <span class="comment">/* C routine to process image */</span>
<a name="l02369"></a>02369         iC[3] = (int) ((C &gt;&gt; 24) &amp; 0xff);
<a name="l02370"></a>02370         iC[2] = (int) ((C &gt;&gt; 16) &amp; 0xff);
<a name="l02371"></a>02371         iC[1] = (int) ((C &gt;&gt;  8) &amp; 0xff);
<a name="l02372"></a>02372         iC[0] = (int) ((C &gt;&gt;  0) &amp; 0xff);
<a name="l02373"></a>02373         <span class="keywordflow">for</span> (i = istart; i &lt; length; i += 4) {
<a name="l02374"></a>02374                 <span class="keywordflow">for</span> (j = 0; j &lt; 4; j++) {
<a name="l02375"></a>02375                         <span class="keywordflow">if</span> ((i+j)&lt;length) {
<a name="l02376"></a>02376                                 result = (int) *cursrc1 - iC[j];
<a name="l02377"></a>02377                                 <span class="keywordflow">if</span> (result &lt; 0) result = 0;
<a name="l02378"></a>02378                                 *curdest = (<span class="keywordtype">unsigned</span> char) result;
<a name="l02379"></a>02379                                 <span class="comment">/* Advance pointers */</span>
<a name="l02380"></a>02380                                 cursrc1++;
<a name="l02381"></a>02381                                 curdest++;
<a name="l02382"></a>02382                         }
<a name="l02383"></a>02383                 }
<a name="l02384"></a>02384         }
<a name="l02385"></a>02385         <span class="keywordflow">return</span> (0);
<a name="l02386"></a>02386 }
<a name="l02387"></a>02387 
<a name="l02399"></a>02399 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterShiftRightMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> N,
<a name="l02400"></a>02400                                                                  <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Mask)
<a name="l02401"></a>02401 {
<a name="l02402"></a>02402 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l02403"></a>02403 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l02404"></a>02404 <span class="preprocessor"></span>        __asm
<a name="l02405"></a>02405         {
<a name="l02406"></a>02406                 pusha
<a name="l02407"></a>02407                         mov edx, Mask           <span class="comment">/* load Mask address into edx */</span>
<a name="l02408"></a>02408                         movq mm0, [edx]         <span class="comment">/* load Mask into mm0 */</span>
<a name="l02409"></a>02409                 xor ecx, ecx    <span class="comment">/* zero ECX */</span>
<a name="l02410"></a>02410                         mov cl,  N      <span class="comment">/* load loop counter (N) into CL */</span>
<a name="l02411"></a>02411                         movd mm3,  ecx  <span class="comment">/* copy (N) into MM3  */</span>
<a name="l02412"></a>02412                         pcmpeqb mm1, mm1        <span class="comment">/* generate all 1&#39;s in mm1 */</span>
<a name="l02413"></a>02413 L10240:                         <span class="comment">/* ** Prepare proper bit-Mask in MM1 ** */</span>
<a name="l02414"></a>02414                 psrlw mm1,  1   <span class="comment">/* shift 4 WORDS of MM1 1 bit to the right */</span>
<a name="l02415"></a>02415                         pand mm1, mm0   <span class="comment">// apply Mask to 8 BYTES of MM1 */</span>
<a name="l02416"></a>02416                         <span class="comment">/*  byte     0x0f, 0xdb, 0xc8 */</span>
<a name="l02417"></a>02417                         dec               cl            <span class="comment">/* decrease loop counter */</span>
<a name="l02418"></a>02418                         jnz            L10240           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l02419"></a>02419                         <span class="comment">/* ** Shift all bytes of the image ** */</span>
<a name="l02420"></a>02420                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l02421"></a>02421                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l02422"></a>02422                         mov ecx,  SrcLength     <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l02423"></a>02423                         shr ecx,  3     <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l02424"></a>02424                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l02425"></a>02425 L10241:
<a name="l02426"></a>02426                 movq mm0, [eax]         <span class="comment">/* load 8 bytes from SrcDest into MM0 */</span>
<a name="l02427"></a>02427                 psrlw mm0, mm3          <span class="comment">/* shift 4 WORDS of MM0 (N) bits to the right */</span>
<a name="l02428"></a>02428                         pand mm0, mm1    <span class="comment">// apply proper bit-Mask to 8 BYTES of MM0 */</span>
<a name="l02429"></a>02429                         <span class="comment">/* byte     0x0f, 0xdb, 0xc1 */</span>
<a name="l02430"></a>02430                         movq [edi], mm0         <span class="comment">/* store result in SrcDest */</span>
<a name="l02431"></a>02431                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l02432"></a>02432                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l02433"></a>02433                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l02434"></a>02434                         jnz            L10241           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l02435"></a>02435                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l02436"></a>02436                         popa
<a name="l02437"></a>02437         }
<a name="l02438"></a>02438 <span class="preprocessor">#else</span>
<a name="l02439"></a>02439 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l02440"></a>02440         __m64 *mSrc1 = (__m64*)Src1;
<a name="l02441"></a>02441         __m64 *mDest = (__m64*)Dest;
<a name="l02442"></a>02442         __m64 *mMask = (__m64*)Mask;
<a name="l02443"></a>02443         __m64 mm1;
<a name="l02444"></a>02444         <span class="keywordtype">int</span> i;
<a name="l02445"></a>02445         mm1 = _m_pcmpeqb(mm1, mm1);                     <span class="comment">/* generate all 1&#39;s in mm1 */</span>
<a name="l02446"></a>02446         <span class="comment">/* Prepare proper bit-Mask in MM1 */</span>
<a name="l02447"></a>02447         <span class="keywordflow">for</span> (i = 0; i &lt; N; i++) {
<a name="l02448"></a>02448                 mm1 = _m_psrlwi(mm1, 1);                <span class="comment">/* shift 4 WORDS of MM1 1 bit to the right */</span>
<a name="l02449"></a>02449                 mm1 = _m_pand(mm1, *mMask);             <span class="comment">/* apply Mask to 8 BYTES of MM1 */</span>
<a name="l02450"></a>02450         }
<a name="l02451"></a>02451         <span class="comment">/* Shift all bytes of the image */</span>
<a name="l02452"></a>02452         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l02453"></a>02453                 __m64 mm0 = _m_psrlwi(*mSrc1, N);       <span class="comment">/* shift 4 WORDS of MM0 (N) bits to the right */</span>
<a name="l02454"></a>02454                 *mDest = _m_pand(mm0, mm1);             <span class="comment">/* apply proper bit-Mask to 8 BYTES of MM0 */</span>
<a name="l02455"></a>02455                 mSrc1++;
<a name="l02456"></a>02456                 mDest++;
<a name="l02457"></a>02457         }
<a name="l02458"></a>02458         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l02459"></a>02459 <span class="preprocessor">#endif</span>
<a name="l02460"></a>02460 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l02461"></a>02461 <span class="preprocessor">#else</span>
<a name="l02462"></a>02462 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l02463"></a>02463 <span class="preprocessor">#endif</span>
<a name="l02464"></a>02464 <span class="preprocessor"></span>}
<a name="l02465"></a>02465 
<a name="l02476"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a1ed688eb128d71af36386e9853d001a9">02476</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a68851aed2dcc5dfd2f3b258236f3b88c" title="Filter using ShiftRight: D = saturation0(S &gt;&gt; N)">SDL_imageFilterShiftRight</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> N)
<a name="l02477"></a>02477 {
<a name="l02478"></a>02478         <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Mask[8] = { 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F };
<a name="l02479"></a>02479         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l02480"></a>02480         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1;
<a name="l02481"></a>02481         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *curdest;
<a name="l02482"></a>02482 
<a name="l02483"></a>02483         <span class="comment">/* Validate input parameters */</span>
<a name="l02484"></a>02484         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l02485"></a>02485                 <span class="keywordflow">return</span>(-1);
<a name="l02486"></a>02486         <span class="keywordflow">if</span> (length == 0)
<a name="l02487"></a>02487                 <span class="keywordflow">return</span>(0);
<a name="l02488"></a>02488 
<a name="l02489"></a>02489         <span class="comment">/* Check shift */</span>
<a name="l02490"></a>02490         <span class="keywordflow">if</span> (N &gt; 8) {
<a name="l02491"></a>02491                 <span class="keywordflow">return</span> (-1);
<a name="l02492"></a>02492         }
<a name="l02493"></a>02493 
<a name="l02494"></a>02494         <span class="comment">/* Special case: N==0 */</span>
<a name="l02495"></a>02495         <span class="keywordflow">if</span> (N == 0) {
<a name="l02496"></a>02496                 memcpy(Src1, Dest, length);
<a name="l02497"></a>02497                 <span class="keywordflow">return</span> (0); 
<a name="l02498"></a>02498         }
<a name="l02499"></a>02499 
<a name="l02500"></a>02500         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l02501"></a>02501 
<a name="l02502"></a>02502                 <span class="comment">/* MMX routine */</span>
<a name="l02503"></a>02503                 SDL_imageFilterShiftRightMMX(Src1, Dest, length, N, Mask);
<a name="l02504"></a>02504 
<a name="l02505"></a>02505                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l02506"></a>02506                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l02507"></a>02507                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l02508"></a>02508                         istart = length &amp; 0xfffffff8;
<a name="l02509"></a>02509                         cursrc1 = &amp;Src1[istart];
<a name="l02510"></a>02510                         curdest = &amp;Dest[istart];
<a name="l02511"></a>02511                 } <span class="keywordflow">else</span> {
<a name="l02512"></a>02512                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l02513"></a>02513                         <span class="keywordflow">return</span> (0);
<a name="l02514"></a>02514                 }
<a name="l02515"></a>02515         } <span class="keywordflow">else</span> {
<a name="l02516"></a>02516                 <span class="comment">/* Setup to process whole image */</span>
<a name="l02517"></a>02517                 istart = 0;
<a name="l02518"></a>02518                 cursrc1 = Src1;
<a name="l02519"></a>02519                 curdest = Dest;
<a name="l02520"></a>02520         }
<a name="l02521"></a>02521 
<a name="l02522"></a>02522         <span class="comment">/* C routine to process image */</span>
<a name="l02523"></a>02523         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l02524"></a>02524                 *curdest = (<span class="keywordtype">unsigned</span> char) *cursrc1 &gt;&gt; N;
<a name="l02525"></a>02525                 <span class="comment">/* Advance pointers */</span>
<a name="l02526"></a>02526                 cursrc1++;
<a name="l02527"></a>02527                 curdest++;
<a name="l02528"></a>02528         }
<a name="l02529"></a>02529 
<a name="l02530"></a>02530         <span class="keywordflow">return</span> (0);
<a name="l02531"></a>02531 }
<a name="l02532"></a>02532 
<a name="l02543"></a>02543 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterShiftRightUintMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> N)
<a name="l02544"></a>02544 {
<a name="l02545"></a>02545 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l02546"></a>02546 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l02547"></a>02547 <span class="preprocessor"></span>        __asm
<a name="l02548"></a>02548         {
<a name="l02549"></a>02549                 pusha
<a name="l02550"></a>02550                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l02551"></a>02551                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l02552"></a>02552                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l02553"></a>02553                         shr ecx, 3      <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l02554"></a>02554                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l02555"></a>02555 L13023:
<a name="l02556"></a>02556                 movq mm0, [eax]         <span class="comment">/* load 8 bytes from SrcDest into MM0 */</span>
<a name="l02557"></a>02557                 psrld mm0, N
<a name="l02558"></a>02558                         movq [edi], mm0         <span class="comment">/* store result in SrcDest */</span>
<a name="l02559"></a>02559                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l02560"></a>02560                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l02561"></a>02561                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l02562"></a>02562                         jnz             L13023          <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l02563"></a>02563                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l02564"></a>02564                         popa
<a name="l02565"></a>02565         }
<a name="l02566"></a>02566 <span class="preprocessor">#else</span>
<a name="l02567"></a>02567 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l02568"></a>02568         __m64 *mSrc1 = (__m64*)Src1;
<a name="l02569"></a>02569         __m64 *mDest = (__m64*)Dest;
<a name="l02570"></a>02570         <span class="keywordtype">int</span> i;
<a name="l02571"></a>02571         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l02572"></a>02572                 *mDest = _m_psrldi(*mSrc1, N);
<a name="l02573"></a>02573                 mSrc1++;
<a name="l02574"></a>02574                 mDest++;
<a name="l02575"></a>02575         }
<a name="l02576"></a>02576         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l02577"></a>02577 <span class="preprocessor">#endif</span>
<a name="l02578"></a>02578 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l02579"></a>02579 <span class="preprocessor">#else</span>
<a name="l02580"></a>02580 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l02581"></a>02581 <span class="preprocessor">#endif</span>
<a name="l02582"></a>02582 <span class="preprocessor"></span>}
<a name="l02583"></a>02583 
<a name="l02594"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a2e5ec075145b34c5ea797ffa70891e53">02594</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a540d4625d76bcd03318c2a59ce650fdb" title="Filter using ShiftRightUint: D = saturation0((uint)S[i] &gt;&gt; N)">SDL_imageFilterShiftRightUint</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> N)
<a name="l02595"></a>02595 {
<a name="l02596"></a>02596         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l02597"></a>02597         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *curdest;
<a name="l02598"></a>02598         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> *icursrc1, *icurdest;
<a name="l02599"></a>02599         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> result;
<a name="l02600"></a>02600 
<a name="l02601"></a>02601         <span class="comment">/* Validate input parameters */</span>
<a name="l02602"></a>02602         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l02603"></a>02603                 <span class="keywordflow">return</span>(-1);
<a name="l02604"></a>02604         <span class="keywordflow">if</span> (length == 0)
<a name="l02605"></a>02605                 <span class="keywordflow">return</span>(0);
<a name="l02606"></a>02606 
<a name="l02607"></a>02607         <span class="keywordflow">if</span> (N &gt; 32) {
<a name="l02608"></a>02608                 <span class="keywordflow">return</span> (-1);
<a name="l02609"></a>02609         }
<a name="l02610"></a>02610 
<a name="l02611"></a>02611         <span class="comment">/* Special case: N==0 */</span>
<a name="l02612"></a>02612         <span class="keywordflow">if</span> (N == 0) {
<a name="l02613"></a>02613                 memcpy(Src1, Dest, length);
<a name="l02614"></a>02614                 <span class="keywordflow">return</span> (0); 
<a name="l02615"></a>02615         }
<a name="l02616"></a>02616 
<a name="l02617"></a>02617         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l02618"></a>02618 
<a name="l02619"></a>02619                 SDL_imageFilterShiftRightUintMMX(Src1, Dest, length, N);
<a name="l02620"></a>02620 
<a name="l02621"></a>02621                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l02622"></a>02622                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l02623"></a>02623                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l02624"></a>02624                         istart = length &amp; 0xfffffff8;
<a name="l02625"></a>02625                         cursrc1 = &amp;Src1[istart];
<a name="l02626"></a>02626                         curdest = &amp;Dest[istart];
<a name="l02627"></a>02627                 } <span class="keywordflow">else</span> {
<a name="l02628"></a>02628                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l02629"></a>02629                         <span class="keywordflow">return</span> (0);
<a name="l02630"></a>02630                 }
<a name="l02631"></a>02631         } <span class="keywordflow">else</span> {
<a name="l02632"></a>02632                 <span class="comment">/* Setup to process whole image */</span>
<a name="l02633"></a>02633                 istart = 0;
<a name="l02634"></a>02634                 cursrc1 = Src1;
<a name="l02635"></a>02635                 curdest = Dest;
<a name="l02636"></a>02636         }
<a name="l02637"></a>02637 
<a name="l02638"></a>02638         <span class="comment">/* C routine to process image */</span>
<a name="l02639"></a>02639         icursrc1=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> *)cursrc1;
<a name="l02640"></a>02640         icurdest=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> *)curdest;
<a name="l02641"></a>02641         <span class="keywordflow">for</span> (i = istart; i &lt; length; i += 4) {
<a name="l02642"></a>02642                 <span class="keywordflow">if</span> ((i+4)&lt;length) {
<a name="l02643"></a>02643                         result = ((<span class="keywordtype">unsigned</span> int)*icursrc1 &gt;&gt; N);
<a name="l02644"></a>02644                         *icurdest = result;
<a name="l02645"></a>02645                 }
<a name="l02646"></a>02646                 <span class="comment">/* Advance pointers */</span>
<a name="l02647"></a>02647                 icursrc1++;
<a name="l02648"></a>02648                 icurdest++;
<a name="l02649"></a>02649         }
<a name="l02650"></a>02650 
<a name="l02651"></a>02651         <span class="keywordflow">return</span> (0);
<a name="l02652"></a>02652 }
<a name="l02653"></a>02653 
<a name="l02664"></a>02664 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterMultByByteMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> C)
<a name="l02665"></a>02665 {
<a name="l02666"></a>02666 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l02667"></a>02667 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l02668"></a>02668 <span class="preprocessor"></span>        __asm
<a name="l02669"></a>02669         {
<a name="l02670"></a>02670                 pusha
<a name="l02671"></a>02671                         <span class="comment">/* ** Duplicate C in 4 words of MM1 ** */</span>
<a name="l02672"></a>02672                         mov al, C       <span class="comment">/* load C into AL */</span>
<a name="l02673"></a>02673                         xor ah, ah      <span class="comment">/* zero AH */</span>
<a name="l02674"></a>02674                         mov bx, ax      <span class="comment">/* copy AX into BX */</span>
<a name="l02675"></a>02675                         shl eax, 16     <span class="comment">/* shift 2 bytes of EAX left */</span>
<a name="l02676"></a>02676                         mov ax, bx      <span class="comment">/* copy BX into AX */</span>
<a name="l02677"></a>02677                         movd mm1, eax           <span class="comment">/* copy EAX into MM1 */</span>
<a name="l02678"></a>02678                         movd mm2, eax           <span class="comment">/* copy EAX into MM2 */</span>
<a name="l02679"></a>02679                         punpckldq mm1, mm2      <span class="comment">/* fill higher words of MM1 with C */</span>
<a name="l02680"></a>02680                         pxor mm0, mm0           <span class="comment">/* zero MM0 register */</span>
<a name="l02681"></a>02681                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l02682"></a>02682                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l02683"></a>02683                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l02684"></a>02684                         shr ecx, 3      <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l02685"></a>02685                         cmp al, 128     <span class="comment">/* if (C &lt;= 128) execute more efficient code */</span>
<a name="l02686"></a>02686                         jg             L10251
<a name="l02687"></a>02687                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l02688"></a>02688 L10250:
<a name="l02689"></a>02689                 movq mm3, [eax]         <span class="comment">/* load 8 bytes from Src1 into MM3 */</span>
<a name="l02690"></a>02690                 movq mm4, mm3           <span class="comment">/* copy MM3 into MM4  */</span>
<a name="l02691"></a>02691                         punpcklbw mm3, mm0      <span class="comment">/* unpack low  bytes of SrcDest into words */</span>
<a name="l02692"></a>02692                         punpckhbw mm4, mm0      <span class="comment">/* unpack high bytes of SrcDest into words */</span>
<a name="l02693"></a>02693                         pmullw mm3, mm1         <span class="comment">/* mul low  bytes of SrcDest and MM1 */</span>
<a name="l02694"></a>02694                         pmullw mm4, mm1         <span class="comment">/* mul high bytes of SrcDest and MM1 */</span>
<a name="l02695"></a>02695                         packuswb mm3, mm4       <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l02696"></a>02696                         movq [edi], mm3         <span class="comment">/* store result in Dest */</span>
<a name="l02697"></a>02697                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l02698"></a>02698                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l02699"></a>02699                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l02700"></a>02700                         jnz            L10250           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l02701"></a>02701                         jmp            L10252
<a name="l02702"></a>02702                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l02703"></a>02703 L10251:
<a name="l02704"></a>02704                 movq mm3, [eax]         <span class="comment">/* load 8 bytes from Src1 into MM3 */</span>
<a name="l02705"></a>02705                 movq mm4, mm3           <span class="comment">/* copy MM3 into MM4  */</span>
<a name="l02706"></a>02706                         punpcklbw mm3, mm0      <span class="comment">/* unpack low  bytes of SrcDest into words */</span>
<a name="l02707"></a>02707                         punpckhbw mm4, mm0      <span class="comment">/* unpack high bytes of SrcDest into words */</span>
<a name="l02708"></a>02708                         pmullw mm3, mm1         <span class="comment">/* mul low  bytes of SrcDest and MM1 */</span>
<a name="l02709"></a>02709                         pmullw mm4, mm1         <span class="comment">/* mul high bytes of SrcDest and MM1 */</span>
<a name="l02710"></a>02710                         <span class="comment">/* ** Take abs value of the results (signed words) ** */</span>
<a name="l02711"></a>02711                         movq mm5, mm3           <span class="comment">/* copy mm3 into mm5 */</span>
<a name="l02712"></a>02712                         movq mm6, mm4           <span class="comment">/* copy mm4 into mm6 */</span>
<a name="l02713"></a>02713                         psraw mm5, 15           <span class="comment">/* fill mm5 words with word sign bit */</span>
<a name="l02714"></a>02714                         psraw mm6, 15           <span class="comment">/* fill mm6 words with word sign bit */</span>
<a name="l02715"></a>02715                         pxor mm3, mm5           <span class="comment">/* take 1&#39;s compliment of only neg words */</span>
<a name="l02716"></a>02716                         pxor mm4, mm6           <span class="comment">/* take 1&#39;s compliment of only neg words */</span>
<a name="l02717"></a>02717                         psubsw mm3, mm5         <span class="comment">/* add 1 to only neg words, W-(-1) or W-0 */</span>
<a name="l02718"></a>02718                         psubsw mm4, mm6         <span class="comment">/* add 1 to only neg words, W-(-1) or W-0 */</span>
<a name="l02719"></a>02719                         packuswb mm3, mm4       <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l02720"></a>02720                         movq [edi], mm3         <span class="comment">/* store result in Dest */</span>
<a name="l02721"></a>02721                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l02722"></a>02722                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l02723"></a>02723                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l02724"></a>02724                         jnz            L10251           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l02725"></a>02725 L10252:
<a name="l02726"></a>02726                 emms                            <span class="comment">/* exit MMX state */</span>
<a name="l02727"></a>02727                         popa
<a name="l02728"></a>02728         }
<a name="l02729"></a>02729 <span class="preprocessor">#else</span>
<a name="l02730"></a>02730 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l02731"></a>02731         __m64 *mSrc1 = (__m64*)Src1;
<a name="l02732"></a>02732         __m64 *mDest = (__m64*)Dest;
<a name="l02733"></a>02733         __m64 mm0 = _m_from_int(0);                             <span class="comment">/* zero mm0 register */</span>
<a name="l02734"></a>02734         <span class="comment">/* Duplicate C in 4 words of MM1 */</span>
<a name="l02735"></a>02735         <span class="keywordtype">int</span> i;
<a name="l02736"></a>02736         i = C | C&lt;&lt;16;
<a name="l02737"></a>02737         __m64 mm1 = _m_from_int(i);
<a name="l02738"></a>02738         __m64 mm2 = _m_from_int(i);
<a name="l02739"></a>02739         mm1 = _m_punpckldq(mm1, mm2);                           <span class="comment">/* fill higher words of MM1 with C */</span>
<a name="l02740"></a>02740         <span class="comment">// long long lli = C | C&lt;&lt;16 | (long long)C&lt;&lt;32 | (long long)C&lt;&lt;48;</span>
<a name="l02741"></a>02741         <span class="comment">//__m64 mm1 = _m_from_int64(lli); // x86_64 only</span>
<a name="l02742"></a>02742         <span class="keywordflow">if</span> (C &lt;= 128) {                                         <span class="comment">/* if (C &lt;= 128) execute more efficient code */</span>
<a name="l02743"></a>02743                 <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l02744"></a>02744                         __m64 mm3, mm4;
<a name="l02745"></a>02745                         mm3 = _m_punpcklbw(*mSrc1, mm0);        <span class="comment">/* unpack low  bytes of Src1 into words */</span>
<a name="l02746"></a>02746                         mm4 = _m_punpckhbw(*mSrc1, mm0);        <span class="comment">/* unpack high bytes of Src1 into words */</span>
<a name="l02747"></a>02747                         mm3 = _m_pmullw(mm3, mm1);              <span class="comment">/* mul low  bytes of Src1 and MM1 */</span>
<a name="l02748"></a>02748                         mm4 = _m_pmullw(mm4, mm1);              <span class="comment">/* mul high bytes of Src1 and MM1 */</span>
<a name="l02749"></a>02749                         *mDest = _m_packuswb(mm3, mm4);         <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l02750"></a>02750                         mSrc1++;
<a name="l02751"></a>02751                         mDest++;
<a name="l02752"></a>02752                 }
<a name="l02753"></a>02753         } <span class="keywordflow">else</span> {
<a name="l02754"></a>02754                 <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l02755"></a>02755                         __m64 mm3, mm4, mm5, mm6;
<a name="l02756"></a>02756                         mm3 = _m_punpcklbw(*mSrc1, mm0);        <span class="comment">/* unpack low  bytes of Src1 into words */</span>
<a name="l02757"></a>02757                         mm4 = _m_punpckhbw(*mSrc1, mm0);        <span class="comment">/* unpack high bytes of Src1 into words */</span>
<a name="l02758"></a>02758                         mm3 = _m_pmullw(mm3, mm1);              <span class="comment">/* mul low  bytes of Src1 and MM1 */</span>
<a name="l02759"></a>02759                         mm4 = _m_pmullw(mm4, mm1);              <span class="comment">/* mul high bytes of Src1 and MM1 */</span>
<a name="l02760"></a>02760                         <span class="comment">/* Take abs value of the results (signed words) */</span>
<a name="l02761"></a>02761                         mm5 = _m_psrawi(mm3, 15);               <span class="comment">/* fill mm5 words with word sign bit */</span>
<a name="l02762"></a>02762                         mm6 = _m_psrawi(mm4, 15);               <span class="comment">/* fill mm6 words with word sign bit */</span>
<a name="l02763"></a>02763                         mm3 = _m_pxor(mm3, mm5);                <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l02764"></a>02764                         mm4 = _m_pxor(mm4, mm6);                <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l02765"></a>02765                         mm3 = _m_psubsw(mm3, mm5);              <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l02766"></a>02766                         mm4 = _m_psubsw(mm4, mm6);              <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l02767"></a>02767                         *mDest = _m_packuswb(mm3, mm4);         <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l02768"></a>02768                         mSrc1++;
<a name="l02769"></a>02769                         mDest++;
<a name="l02770"></a>02770                 }
<a name="l02771"></a>02771         }
<a name="l02772"></a>02772         _m_empty();                                             <span class="comment">/* clean MMX state */</span>
<a name="l02773"></a>02773 <span class="preprocessor">#endif</span>
<a name="l02774"></a>02774 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l02775"></a>02775 <span class="preprocessor">#else</span>
<a name="l02776"></a>02776 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l02777"></a>02777 <span class="preprocessor">#endif</span>
<a name="l02778"></a>02778 <span class="preprocessor"></span>}
<a name="l02779"></a>02779 
<a name="l02790"></a><a class="code" href="_s_d_l2__image_filter_8h.html#aef668f157cc152554872ccac491ee2f7">02790</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a06f7a19d6e2fc89d7b48cc45d715806d" title="Filter using MultByByte: D = saturation255(S * C)">SDL_imageFilterMultByByte</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> C)
<a name="l02791"></a>02791 {
<a name="l02792"></a>02792         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l02793"></a>02793         <span class="keywordtype">int</span> iC;
<a name="l02794"></a>02794         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1;
<a name="l02795"></a>02795         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *curdest;
<a name="l02796"></a>02796         <span class="keywordtype">int</span> result;
<a name="l02797"></a>02797 
<a name="l02798"></a>02798         <span class="comment">/* Validate input parameters */</span>
<a name="l02799"></a>02799         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l02800"></a>02800                 <span class="keywordflow">return</span>(-1);
<a name="l02801"></a>02801         <span class="keywordflow">if</span> (length == 0)
<a name="l02802"></a>02802                 <span class="keywordflow">return</span>(0);
<a name="l02803"></a>02803 
<a name="l02804"></a>02804         <span class="comment">/* Special case: C==1 */</span>
<a name="l02805"></a>02805         <span class="keywordflow">if</span> (C == 1) {
<a name="l02806"></a>02806                 memcpy(Src1, Dest, length);
<a name="l02807"></a>02807                 <span class="keywordflow">return</span> (0); 
<a name="l02808"></a>02808         }
<a name="l02809"></a>02809 
<a name="l02810"></a>02810         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l02811"></a>02811 
<a name="l02812"></a>02812                 SDL_imageFilterMultByByteMMX(Src1, Dest, length, C);
<a name="l02813"></a>02813 
<a name="l02814"></a>02814                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l02815"></a>02815                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l02816"></a>02816                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l02817"></a>02817                         istart = length &amp; 0xfffffff8;
<a name="l02818"></a>02818                         cursrc1 = &amp;Src1[istart];
<a name="l02819"></a>02819                         curdest = &amp;Dest[istart];
<a name="l02820"></a>02820                 } <span class="keywordflow">else</span> {
<a name="l02821"></a>02821                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l02822"></a>02822                         <span class="keywordflow">return</span> (0);
<a name="l02823"></a>02823                 }
<a name="l02824"></a>02824         } <span class="keywordflow">else</span> {
<a name="l02825"></a>02825                 <span class="comment">/* Setup to process whole image */</span>
<a name="l02826"></a>02826                 istart = 0;
<a name="l02827"></a>02827                 cursrc1 = Src1;
<a name="l02828"></a>02828                 curdest = Dest;
<a name="l02829"></a>02829         }
<a name="l02830"></a>02830 
<a name="l02831"></a>02831         <span class="comment">/* C routine to process image */</span>
<a name="l02832"></a>02832         iC = (int) C;
<a name="l02833"></a>02833         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l02834"></a>02834                 result = (int) *cursrc1 * iC;
<a name="l02835"></a>02835                 <span class="keywordflow">if</span> (result &gt; 255)
<a name="l02836"></a>02836                         result = 255;
<a name="l02837"></a>02837                 *curdest = (<span class="keywordtype">unsigned</span> char) result;
<a name="l02838"></a>02838                 <span class="comment">/* Advance pointers */</span>
<a name="l02839"></a>02839                 cursrc1++;
<a name="l02840"></a>02840                 curdest++;
<a name="l02841"></a>02841         }
<a name="l02842"></a>02842 
<a name="l02843"></a>02843         <span class="keywordflow">return</span> (0);
<a name="l02844"></a>02844 }
<a name="l02845"></a>02845 
<a name="l02857"></a>02857 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterShiftRightAndMultByByteMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> N,
<a name="l02858"></a>02858                                                                                           <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> C)
<a name="l02859"></a>02859 {
<a name="l02860"></a>02860 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l02861"></a>02861 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l02862"></a>02862 <span class="preprocessor"></span>        __asm
<a name="l02863"></a>02863         {
<a name="l02864"></a>02864                 pusha
<a name="l02865"></a>02865                         <span class="comment">/* ** Duplicate C in 4 words of MM1 ** */</span>
<a name="l02866"></a>02866                         mov al, C       <span class="comment">/* load C into AL */</span>
<a name="l02867"></a>02867                         xor ah, ah      <span class="comment">/* zero AH */</span>
<a name="l02868"></a>02868                         mov bx, ax      <span class="comment">/* copy AX into BX */</span>
<a name="l02869"></a>02869                         shl eax, 16     <span class="comment">/* shift 2 bytes of EAX left */</span>
<a name="l02870"></a>02870                         mov ax, bx      <span class="comment">/* copy BX into AX */</span>
<a name="l02871"></a>02871                         movd mm1, eax           <span class="comment">/* copy EAX into MM1 */</span>
<a name="l02872"></a>02872                         movd mm2, eax           <span class="comment">/* copy EAX into MM2 */</span>
<a name="l02873"></a>02873                         punpckldq mm1, mm2      <span class="comment">/* fill higher words of MM1 with C */</span>
<a name="l02874"></a>02874                         xor ecx, ecx    <span class="comment">/* zero ECX */</span>
<a name="l02875"></a>02875                         mov cl, N       <span class="comment">/* load N into CL */</span>
<a name="l02876"></a>02876                         movd mm7, ecx           <span class="comment">/* copy N into MM7 */</span>
<a name="l02877"></a>02877                         pxor mm0, mm0           <span class="comment">/* zero MM0 register */</span>
<a name="l02878"></a>02878                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l02879"></a>02879                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l02880"></a>02880                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l02881"></a>02881                         shr ecx, 3      <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l02882"></a>02882                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l02883"></a>02883 L1026:
<a name="l02884"></a>02884                 movq mm3, [eax]         <span class="comment">/* load 8 bytes from Src1 into MM3 */</span>
<a name="l02885"></a>02885                 movq mm4, mm3           <span class="comment">/* copy MM3 into MM4  */</span>
<a name="l02886"></a>02886                         punpcklbw mm3, mm0      <span class="comment">/* unpack low  bytes of SrcDest into words */</span>
<a name="l02887"></a>02887                         punpckhbw mm4, mm0      <span class="comment">/* unpack high bytes of SrcDest into words */</span>
<a name="l02888"></a>02888                         psrlw mm3, mm7          <span class="comment">/* shift 4 WORDS of MM3 (N) bits to the right */</span>
<a name="l02889"></a>02889                         psrlw mm4, mm7          <span class="comment">/* shift 4 WORDS of MM4 (N) bits to the right */</span>
<a name="l02890"></a>02890                         pmullw mm3, mm1         <span class="comment">/* mul low  bytes of SrcDest by MM1 */</span>
<a name="l02891"></a>02891                         pmullw mm4, mm1         <span class="comment">/* mul high bytes of SrcDest by MM1 */</span>
<a name="l02892"></a>02892                         packuswb mm3, mm4       <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l02893"></a>02893                         movq [edi], mm3         <span class="comment">/* store result in Dest */</span>
<a name="l02894"></a>02894                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l02895"></a>02895                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l02896"></a>02896                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l02897"></a>02897                         jnz             L1026           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l02898"></a>02898                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l02899"></a>02899                         popa
<a name="l02900"></a>02900         }
<a name="l02901"></a>02901 <span class="preprocessor">#else</span>
<a name="l02902"></a>02902 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l02903"></a>02903         __m64 *mSrc1 = (__m64*)Src1;
<a name="l02904"></a>02904         __m64 *mDest = (__m64*)Dest;
<a name="l02905"></a>02905         __m64 mm0 = _m_from_int(0);                     <span class="comment">/* zero mm0 register */</span>
<a name="l02906"></a>02906         <span class="comment">/* Duplicate C in 4 words of MM1 */</span>
<a name="l02907"></a>02907         <span class="keywordtype">int</span> i;
<a name="l02908"></a>02908         i = (C&lt;&lt;16)|C;
<a name="l02909"></a>02909         __m64 mm1 = _m_from_int(i);
<a name="l02910"></a>02910         __m64 mm2 = _m_from_int(i);
<a name="l02911"></a>02911         mm1 = _m_punpckldq(mm1, mm2);                   <span class="comment">/* fill higher words of MM1 with C */</span>
<a name="l02912"></a>02912         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l02913"></a>02913                 __m64 mm3, mm4, mm5, mm6;
<a name="l02914"></a>02914                 mm3 = _m_punpcklbw(*mSrc1, mm0);        <span class="comment">/* unpack low  bytes of Src1 into words */</span>
<a name="l02915"></a>02915                 mm4 = _m_punpckhbw(*mSrc1, mm0);        <span class="comment">/* unpack high bytes of Src1 into words */</span>
<a name="l02916"></a>02916                 mm3 = _m_psrlwi(mm3, N);                <span class="comment">/* shift 4 WORDS of MM3 (N) bits to the right */</span>
<a name="l02917"></a>02917                 mm4 = _m_psrlwi(mm4, N);                <span class="comment">/* shift 4 WORDS of MM4 (N) bits to the right */</span>
<a name="l02918"></a>02918                 mm3 = _m_pmullw(mm3, mm1);              <span class="comment">/* mul low  bytes of Src1 and MM1 */</span>
<a name="l02919"></a>02919                 mm4 = _m_pmullw(mm4, mm1);              <span class="comment">/* mul high bytes of Src1 and MM1 */</span>
<a name="l02920"></a>02920                 *mDest = _m_packuswb(mm3, mm4);         <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l02921"></a>02921                 mSrc1++;
<a name="l02922"></a>02922                 mDest++;
<a name="l02923"></a>02923         }
<a name="l02924"></a>02924         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l02925"></a>02925 <span class="preprocessor">#endif</span>
<a name="l02926"></a>02926 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l02927"></a>02927 <span class="preprocessor">#else</span>
<a name="l02928"></a>02928 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l02929"></a>02929 <span class="preprocessor">#endif</span>
<a name="l02930"></a>02930 <span class="preprocessor"></span>}
<a name="l02931"></a>02931 
<a name="l02943"></a><a class="code" href="_s_d_l2__image_filter_8h.html#ad8d11768b921ba823d412166903340b8">02943</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a0713d6c267fba9756d6beae81e89f9e4" title="Filter using ShiftRightAndMultByByte: D = saturation255((S &gt;&gt; N) * C)">SDL_imageFilterShiftRightAndMultByByte</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> N,
<a name="l02944"></a>02944                                                                                    <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> C)
<a name="l02945"></a>02945 {
<a name="l02946"></a>02946         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l02947"></a>02947         <span class="keywordtype">int</span> iC;
<a name="l02948"></a>02948         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1;
<a name="l02949"></a>02949         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *curdest;
<a name="l02950"></a>02950         <span class="keywordtype">int</span> result;
<a name="l02951"></a>02951 
<a name="l02952"></a>02952         <span class="comment">/* Validate input parameters */</span>
<a name="l02953"></a>02953         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l02954"></a>02954                 <span class="keywordflow">return</span>(-1);
<a name="l02955"></a>02955         <span class="keywordflow">if</span> (length == 0)
<a name="l02956"></a>02956                 <span class="keywordflow">return</span>(0);
<a name="l02957"></a>02957 
<a name="l02958"></a>02958         <span class="comment">/* Check shift */</span>
<a name="l02959"></a>02959         <span class="keywordflow">if</span> (N &gt; 8) {
<a name="l02960"></a>02960                 <span class="keywordflow">return</span> (-1);
<a name="l02961"></a>02961         }
<a name="l02962"></a>02962 
<a name="l02963"></a>02963         <span class="comment">/* Special case: N==0 &amp;&amp; C==1 */</span>
<a name="l02964"></a>02964         <span class="keywordflow">if</span> ((N == 0) &amp;&amp; (C == 1)) {
<a name="l02965"></a>02965                 memcpy(Src1, Dest, length);
<a name="l02966"></a>02966                 <span class="keywordflow">return</span> (0); 
<a name="l02967"></a>02967         }
<a name="l02968"></a>02968 
<a name="l02969"></a>02969         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l02970"></a>02970 
<a name="l02971"></a>02971                 SDL_imageFilterShiftRightAndMultByByteMMX(Src1, Dest, length, N, C);
<a name="l02972"></a>02972 
<a name="l02973"></a>02973                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l02974"></a>02974                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l02975"></a>02975                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l02976"></a>02976                         istart = length &amp; 0xfffffff8;
<a name="l02977"></a>02977                         cursrc1 = &amp;Src1[istart];
<a name="l02978"></a>02978                         curdest = &amp;Dest[istart];
<a name="l02979"></a>02979                 } <span class="keywordflow">else</span> {
<a name="l02980"></a>02980                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l02981"></a>02981                         <span class="keywordflow">return</span> (0);
<a name="l02982"></a>02982                 }
<a name="l02983"></a>02983         } <span class="keywordflow">else</span> {
<a name="l02984"></a>02984                 <span class="comment">/* Setup to process whole image */</span>
<a name="l02985"></a>02985                 istart = 0;
<a name="l02986"></a>02986                 cursrc1 = Src1;
<a name="l02987"></a>02987                 curdest = Dest;
<a name="l02988"></a>02988         }
<a name="l02989"></a>02989 
<a name="l02990"></a>02990         <span class="comment">/* C routine to process image */</span>
<a name="l02991"></a>02991         iC = (int) C;
<a name="l02992"></a>02992         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l02993"></a>02993                 result = (int) (*cursrc1 &gt;&gt; N) * iC;
<a name="l02994"></a>02994                 <span class="keywordflow">if</span> (result &gt; 255)
<a name="l02995"></a>02995                         result = 255;
<a name="l02996"></a>02996                 *curdest = (<span class="keywordtype">unsigned</span> char) result;
<a name="l02997"></a>02997                 <span class="comment">/* Advance pointers */</span>
<a name="l02998"></a>02998                 cursrc1++;
<a name="l02999"></a>02999                 curdest++;
<a name="l03000"></a>03000         }
<a name="l03001"></a>03001 
<a name="l03002"></a>03002         <span class="keywordflow">return</span> (0);
<a name="l03003"></a>03003 }
<a name="l03004"></a>03004 
<a name="l03016"></a>03016 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterShiftLeftByteMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> N,
<a name="l03017"></a>03017                                                                         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Mask)
<a name="l03018"></a>03018 {
<a name="l03019"></a>03019 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l03020"></a>03020 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l03021"></a>03021 <span class="preprocessor"></span>        __asm
<a name="l03022"></a>03022         {
<a name="l03023"></a>03023                 pusha
<a name="l03024"></a>03024                         mov edx, Mask           <span class="comment">/* load Mask address into edx */</span>
<a name="l03025"></a>03025                         movq mm0, [edx]         <span class="comment">/* load Mask into mm0 */</span>
<a name="l03026"></a>03026                 xor ecx, ecx    <span class="comment">/* zero ECX */</span>
<a name="l03027"></a>03027                         mov cl, N       <span class="comment">/* load loop counter (N) into CL */</span>
<a name="l03028"></a>03028                         movd mm3, ecx           <span class="comment">/* copy (N) into MM3  */</span>
<a name="l03029"></a>03029                         pcmpeqb mm1, mm1        <span class="comment">/* generate all 1&#39;s in mm1 */</span>
<a name="l03030"></a>03030 L10270:                         <span class="comment">/* ** Prepare proper bit-Mask in MM1 ** */</span>
<a name="l03031"></a>03031                 psllw mm1, 1    <span class="comment">/* shift 4 WORDS of MM1 1 bit to the left */</span>
<a name="l03032"></a>03032                         pand mm1, mm0        <span class="comment">// apply Mask to 8 BYTES of MM1 */</span>
<a name="l03033"></a>03033                         <span class="comment">/*  byte     0x0f, 0xdb, 0xc8 */</span>
<a name="l03034"></a>03034                         dec cl                          <span class="comment">/* decrease loop counter */</span>
<a name="l03035"></a>03035                         jnz            L10270           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l03036"></a>03036                         <span class="comment">/* ** Shift all bytes of the image ** */</span>
<a name="l03037"></a>03037                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l03038"></a>03038                         mov edi, Dest           <span class="comment">/* load SrcDest address into edi */</span>
<a name="l03039"></a>03039                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l03040"></a>03040                         shr ecx, 3      <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l03041"></a>03041                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l03042"></a>03042 L10271:
<a name="l03043"></a>03043                 movq mm0, [eax]         <span class="comment">/* load 8 bytes from Src1 into MM0 */</span>
<a name="l03044"></a>03044                 psllw mm0, mm3          <span class="comment">/* shift 4 WORDS of MM0 (N) bits to the left */</span>
<a name="l03045"></a>03045                         pand mm0, mm1    <span class="comment">// apply proper bit-Mask to 8 BYTES of MM0 */</span>
<a name="l03046"></a>03046                         <span class="comment">/* byte     0x0f, 0xdb, 0xc1 */</span>
<a name="l03047"></a>03047                         movq [edi], mm0         <span class="comment">/* store result in Dest */</span>
<a name="l03048"></a>03048                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l03049"></a>03049                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l03050"></a>03050                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l03051"></a>03051                         jnz            L10271           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l03052"></a>03052                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l03053"></a>03053                         popa
<a name="l03054"></a>03054         }
<a name="l03055"></a>03055 <span class="preprocessor">#else</span>
<a name="l03056"></a>03056 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l03057"></a>03057         __m64 *mSrc1 = (__m64*)Src1;
<a name="l03058"></a>03058         __m64 *mDest = (__m64*)Dest;
<a name="l03059"></a>03059         __m64 *mMask = (__m64*)Mask;
<a name="l03060"></a>03060         __m64 mm1;
<a name="l03061"></a>03061         <span class="keywordtype">int</span> i;
<a name="l03062"></a>03062         mm1 = _m_pcmpeqb(mm1, mm1);                     <span class="comment">/* generate all 1&#39;s in mm1 */</span>
<a name="l03063"></a>03063         <span class="comment">/* Prepare proper bit-Mask in MM1 */</span>
<a name="l03064"></a>03064         <span class="keywordflow">for</span> (i = 0; i &lt; N; i++) {
<a name="l03065"></a>03065                 mm1 = _m_psllwi(mm1, 1);                <span class="comment">/* shift 4 WORDS of MM1 1 bit to the left */</span>
<a name="l03066"></a>03066                 mm1 = _m_pand(mm1, *mMask);             <span class="comment">/* apply Mask to 8 BYTES of MM1 */</span>
<a name="l03067"></a>03067         }
<a name="l03068"></a>03068         <span class="comment">/* ** Shift all bytes of the image ** */</span>
<a name="l03069"></a>03069         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l03070"></a>03070                 __m64 mm0 = _m_psllwi(*mSrc1, N);       <span class="comment">/* shift 4 WORDS of MM0 (N) bits to the left */</span>
<a name="l03071"></a>03071                 *mDest = _m_pand(mm0, mm1);             <span class="comment">/* apply proper bit-Mask to 8 BYTES of MM0 */</span>
<a name="l03072"></a>03072                 mSrc1++;
<a name="l03073"></a>03073                 mDest++;
<a name="l03074"></a>03074         }
<a name="l03075"></a>03075         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l03076"></a>03076 <span class="preprocessor">#endif</span>
<a name="l03077"></a>03077 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l03078"></a>03078 <span class="preprocessor">#else</span>
<a name="l03079"></a>03079 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l03080"></a>03080 <span class="preprocessor">#endif</span>
<a name="l03081"></a>03081 <span class="preprocessor"></span>}
<a name="l03082"></a>03082 
<a name="l03093"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a656657c3f31effa01163532fd96b3011">03093</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a4561a73b249a26babc4c469ffbdae604" title="Filter using ShiftLeftByte: D = (S &lt;&lt; N)">SDL_imageFilterShiftLeftByte</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> N)
<a name="l03094"></a>03094 {
<a name="l03095"></a>03095         <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Mask[8] = { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE };
<a name="l03096"></a>03096         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l03097"></a>03097         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *curdest;
<a name="l03098"></a>03098         <span class="keywordtype">int</span> result;
<a name="l03099"></a>03099 
<a name="l03100"></a>03100         <span class="comment">/* Validate input parameters */</span>
<a name="l03101"></a>03101         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l03102"></a>03102                 <span class="keywordflow">return</span>(-1);
<a name="l03103"></a>03103         <span class="keywordflow">if</span> (length == 0)
<a name="l03104"></a>03104                 <span class="keywordflow">return</span>(0);
<a name="l03105"></a>03105 
<a name="l03106"></a>03106         <span class="keywordflow">if</span> (N &gt; 8) {
<a name="l03107"></a>03107                 <span class="keywordflow">return</span> (-1);
<a name="l03108"></a>03108         }
<a name="l03109"></a>03109 
<a name="l03110"></a>03110         <span class="comment">/* Special case: N==0 */</span>
<a name="l03111"></a>03111         <span class="keywordflow">if</span> (N == 0) {
<a name="l03112"></a>03112                 memcpy(Src1, Dest, length);
<a name="l03113"></a>03113                 <span class="keywordflow">return</span> (0); 
<a name="l03114"></a>03114         }
<a name="l03115"></a>03115 
<a name="l03116"></a>03116         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l03117"></a>03117 
<a name="l03118"></a>03118                 SDL_imageFilterShiftLeftByteMMX(Src1, Dest, length, N, Mask);
<a name="l03119"></a>03119 
<a name="l03120"></a>03120                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l03121"></a>03121                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l03122"></a>03122                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l03123"></a>03123                         istart = length &amp; 0xfffffff8;
<a name="l03124"></a>03124                         cursrc1 = &amp;Src1[istart];
<a name="l03125"></a>03125                         curdest = &amp;Dest[istart];
<a name="l03126"></a>03126                 } <span class="keywordflow">else</span> {
<a name="l03127"></a>03127                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l03128"></a>03128                         <span class="keywordflow">return</span> (0);
<a name="l03129"></a>03129                 }
<a name="l03130"></a>03130         } <span class="keywordflow">else</span> {
<a name="l03131"></a>03131                 <span class="comment">/* Setup to process whole image */</span>
<a name="l03132"></a>03132                 istart = 0;
<a name="l03133"></a>03133                 cursrc1 = Src1;
<a name="l03134"></a>03134                 curdest = Dest;
<a name="l03135"></a>03135         }
<a name="l03136"></a>03136 
<a name="l03137"></a>03137         <span class="comment">/* C routine to process image */</span>
<a name="l03138"></a>03138         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l03139"></a>03139                 result = ((int) *cursrc1 &lt;&lt; N) &amp; 0xff;
<a name="l03140"></a>03140                 *curdest = (<span class="keywordtype">unsigned</span> char) result;
<a name="l03141"></a>03141                 <span class="comment">/* Advance pointers */</span>
<a name="l03142"></a>03142                 cursrc1++;
<a name="l03143"></a>03143                 curdest++;
<a name="l03144"></a>03144         }
<a name="l03145"></a>03145 
<a name="l03146"></a>03146         <span class="keywordflow">return</span> (0);
<a name="l03147"></a>03147 }
<a name="l03148"></a>03148 
<a name="l03159"></a>03159 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterShiftLeftUintMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> N)
<a name="l03160"></a>03160 {
<a name="l03161"></a>03161 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l03162"></a>03162 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l03163"></a>03163 <span class="preprocessor"></span>        __asm
<a name="l03164"></a>03164         {
<a name="l03165"></a>03165                 pusha
<a name="l03166"></a>03166                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l03167"></a>03167                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l03168"></a>03168                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l03169"></a>03169                         shr ecx, 3      <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l03170"></a>03170                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l03171"></a>03171 L12023:
<a name="l03172"></a>03172                 movq mm0, [eax]         <span class="comment">/* load 8 bytes from SrcDest into MM0 */</span>
<a name="l03173"></a>03173                 pslld mm0, N    <span class="comment">/* MM0=SrcDest+C (add 8 bytes with saturation) */</span>
<a name="l03174"></a>03174                         movq [edi], mm0         <span class="comment">/* store result in SrcDest */</span>
<a name="l03175"></a>03175                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l03176"></a>03176                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l03177"></a>03177                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l03178"></a>03178                         jnz             L12023          <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l03179"></a>03179                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l03180"></a>03180                         popa
<a name="l03181"></a>03181         }
<a name="l03182"></a>03182 <span class="preprocessor">#else</span>
<a name="l03183"></a>03183 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l03184"></a>03184         __m64 *mSrc1 = (__m64*)Src1;
<a name="l03185"></a>03185         __m64 *mDest = (__m64*)Dest;
<a name="l03186"></a>03186         <span class="keywordtype">int</span> i;
<a name="l03187"></a>03187         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l03188"></a>03188                 *mDest = _m_pslldi(*mSrc1, N);  <span class="comment">/* Src1+C (add 8 bytes with saturation) */</span>
<a name="l03189"></a>03189                 mSrc1++;
<a name="l03190"></a>03190                 mDest++;
<a name="l03191"></a>03191         }
<a name="l03192"></a>03192         _m_empty();                             <span class="comment">/* clean MMX state */</span>
<a name="l03193"></a>03193 <span class="preprocessor">#endif</span>
<a name="l03194"></a>03194 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l03195"></a>03195 <span class="preprocessor">#else</span>
<a name="l03196"></a>03196 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l03197"></a>03197 <span class="preprocessor">#endif</span>
<a name="l03198"></a>03198 <span class="preprocessor"></span>}
<a name="l03199"></a>03199 
<a name="l03210"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a3ea712cad49735ca672e1d2da1e68516">03210</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a250e796fb2db470da0a78b74b78114e8" title="Filter using ShiftLeftUint: D = ((uint)S &lt;&lt; N)">SDL_imageFilterShiftLeftUint</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> N)
<a name="l03211"></a>03211 {
<a name="l03212"></a>03212         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l03213"></a>03213         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *curdest;
<a name="l03214"></a>03214         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> *icursrc1, *icurdest;
<a name="l03215"></a>03215         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> result;
<a name="l03216"></a>03216 
<a name="l03217"></a>03217         <span class="comment">/* Validate input parameters */</span>
<a name="l03218"></a>03218         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l03219"></a>03219                 <span class="keywordflow">return</span>(-1);
<a name="l03220"></a>03220         <span class="keywordflow">if</span> (length == 0)
<a name="l03221"></a>03221                 <span class="keywordflow">return</span>(0);
<a name="l03222"></a>03222 
<a name="l03223"></a>03223         <span class="keywordflow">if</span> (N &gt; 32) {
<a name="l03224"></a>03224                 <span class="keywordflow">return</span> (-1);
<a name="l03225"></a>03225         }
<a name="l03226"></a>03226 
<a name="l03227"></a>03227         <span class="comment">/* Special case: N==0 */</span>
<a name="l03228"></a>03228         <span class="keywordflow">if</span> (N == 0) {
<a name="l03229"></a>03229                 memcpy(Src1, Dest, length);
<a name="l03230"></a>03230                 <span class="keywordflow">return</span> (0); 
<a name="l03231"></a>03231         }
<a name="l03232"></a>03232 
<a name="l03233"></a>03233         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l03234"></a>03234 
<a name="l03235"></a>03235                 SDL_imageFilterShiftLeftUintMMX(Src1, Dest, length, N);
<a name="l03236"></a>03236 
<a name="l03237"></a>03237                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l03238"></a>03238                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l03239"></a>03239                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l03240"></a>03240                         istart = length &amp; 0xfffffff8;
<a name="l03241"></a>03241                         cursrc1 = &amp;Src1[istart];
<a name="l03242"></a>03242                         curdest = &amp;Dest[istart];
<a name="l03243"></a>03243                 } <span class="keywordflow">else</span> {
<a name="l03244"></a>03244                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l03245"></a>03245                         <span class="keywordflow">return</span> (0);
<a name="l03246"></a>03246                 }
<a name="l03247"></a>03247         } <span class="keywordflow">else</span> {
<a name="l03248"></a>03248                 <span class="comment">/* Setup to process whole image */</span>
<a name="l03249"></a>03249                 istart = 0;
<a name="l03250"></a>03250                 cursrc1 = Src1;
<a name="l03251"></a>03251                 curdest = Dest;
<a name="l03252"></a>03252         }
<a name="l03253"></a>03253 
<a name="l03254"></a>03254         <span class="comment">/* C routine to process image */</span>
<a name="l03255"></a>03255         icursrc1=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> *)cursrc1;
<a name="l03256"></a>03256         icurdest=(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> *)curdest;
<a name="l03257"></a>03257         <span class="keywordflow">for</span> (i = istart; i &lt; length; i += 4) {
<a name="l03258"></a>03258                 <span class="keywordflow">if</span> ((i+4)&lt;length) {
<a name="l03259"></a>03259                         result = ((<span class="keywordtype">unsigned</span> int)*icursrc1 &lt;&lt; N);
<a name="l03260"></a>03260                         *icurdest = result;
<a name="l03261"></a>03261                 }
<a name="l03262"></a>03262                 <span class="comment">/* Advance pointers */</span>
<a name="l03263"></a>03263                 icursrc1++;
<a name="l03264"></a>03264                 icurdest++;
<a name="l03265"></a>03265         }
<a name="l03266"></a>03266 
<a name="l03267"></a>03267         <span class="keywordflow">return</span> (0);
<a name="l03268"></a>03268 }
<a name="l03269"></a>03269 
<a name="l03280"></a>03280 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterShiftLeftMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> N)
<a name="l03281"></a>03281 {
<a name="l03282"></a>03282 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l03283"></a>03283 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l03284"></a>03284 <span class="preprocessor"></span>        __asm
<a name="l03285"></a>03285         {
<a name="l03286"></a>03286                 pusha
<a name="l03287"></a>03287                         xor eax, eax    <span class="comment">/* zero EAX */</span>
<a name="l03288"></a>03288                         mov al, N       <span class="comment">/* load N into AL */</span>
<a name="l03289"></a>03289                         movd mm7, eax           <span class="comment">/* copy N into MM7 */</span>
<a name="l03290"></a>03290                         pxor mm0, mm0           <span class="comment">/* zero MM0 register */</span>
<a name="l03291"></a>03291                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l03292"></a>03292                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l03293"></a>03293                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l03294"></a>03294                         shr ecx, 3      <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l03295"></a>03295                         cmp al, 7       <span class="comment">/* if (N &lt;= 7) execute more efficient code */</span>
<a name="l03296"></a>03296                         jg             L10281
<a name="l03297"></a>03297                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l03298"></a>03298 L10280:
<a name="l03299"></a>03299                 movq mm3, [eax]         <span class="comment">/* load 8 bytes from Src1 into MM3 */</span>
<a name="l03300"></a>03300                 movq mm4, mm3           <span class="comment">/* copy MM3 into MM4  */</span>
<a name="l03301"></a>03301                         punpcklbw mm3, mm0      <span class="comment">/* unpack low  bytes of SrcDest into words */</span>
<a name="l03302"></a>03302                         punpckhbw mm4, mm0      <span class="comment">/* unpack high bytes of SrcDest into words */</span>
<a name="l03303"></a>03303                         psllw mm3, mm7          <span class="comment">/* shift 4 WORDS of MM3 (N) bits to the left */</span>
<a name="l03304"></a>03304                         psllw mm4, mm7          <span class="comment">/* shift 4 WORDS of MM4 (N) bits to the left */</span>
<a name="l03305"></a>03305                         packuswb mm3, mm4       <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l03306"></a>03306                         movq [edi], mm3         <span class="comment">/* store result in Dest */</span>
<a name="l03307"></a>03307                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l03308"></a>03308                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l03309"></a>03309                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l03310"></a>03310                         jnz            L10280           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l03311"></a>03311                         jmp            L10282
<a name="l03312"></a>03312                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l03313"></a>03313 L10281:
<a name="l03314"></a>03314                 movq mm3, [eax]         <span class="comment">/* load 8 bytes from Src1 into MM3 */</span>
<a name="l03315"></a>03315                 movq mm4, mm3           <span class="comment">/* copy MM3 into MM4  */</span>
<a name="l03316"></a>03316                         punpcklbw mm3, mm0      <span class="comment">/* unpack low  bytes of SrcDest into words */</span>
<a name="l03317"></a>03317                         punpckhbw mm4, mm0      <span class="comment">/* unpack high bytes of SrcDest into words */</span>
<a name="l03318"></a>03318                         psllw mm3, mm7          <span class="comment">/* shift 4 WORDS of MM3 (N) bits to the left */</span>
<a name="l03319"></a>03319                         psllw mm4, mm7          <span class="comment">/* shift 4 WORDS of MM4 (N) bits to the left */</span>
<a name="l03320"></a>03320                         <span class="comment">/* ** Take abs value of the signed words ** */</span>
<a name="l03321"></a>03321                         movq mm5, mm3           <span class="comment">/* copy mm3 into mm5 */</span>
<a name="l03322"></a>03322                         movq mm6, mm4           <span class="comment">/* copy mm4 into mm6 */</span>
<a name="l03323"></a>03323                         psraw mm5, 15           <span class="comment">/* fill mm5 words with word sign bit */</span>
<a name="l03324"></a>03324                         psraw mm6, 15           <span class="comment">/* fill mm6 words with word sign bit */</span>
<a name="l03325"></a>03325                         pxor mm3, mm5           <span class="comment">/* take 1&#39;s compliment of only neg words */</span>
<a name="l03326"></a>03326                         pxor mm4, mm6           <span class="comment">/* take 1&#39;s compliment of only neg words */</span>
<a name="l03327"></a>03327                         psubsw mm3, mm5         <span class="comment">/* add 1 to only neg words, W-(-1) or W-0 */</span>
<a name="l03328"></a>03328                         psubsw mm4, mm6         <span class="comment">/* add 1 to only neg words, W-(-1) or W-0 */</span>
<a name="l03329"></a>03329                         packuswb mm3, mm4       <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l03330"></a>03330                         movq [edi], mm3         <span class="comment">/* store result in Dest */</span>
<a name="l03331"></a>03331                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l03332"></a>03332                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l03333"></a>03333                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l03334"></a>03334                         jnz            L10281           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l03335"></a>03335 L10282:
<a name="l03336"></a>03336                 emms                            <span class="comment">/* exit MMX state */</span>
<a name="l03337"></a>03337                         popa
<a name="l03338"></a>03338         }
<a name="l03339"></a>03339 <span class="preprocessor">#else</span>
<a name="l03340"></a>03340 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l03341"></a>03341         __m64 *mSrc1 = (__m64*)Src1;
<a name="l03342"></a>03342         __m64 *mDest = (__m64*)Dest;
<a name="l03343"></a>03343         __m64 mm0 = _m_from_int(0);                             <span class="comment">/* zero mm0 register */</span>
<a name="l03344"></a>03344         <span class="keywordtype">int</span> i;
<a name="l03345"></a>03345         <span class="keywordflow">if</span> (N &lt;= 7) {                                           <span class="comment">/* if (N &lt;= 7) execute more efficient code */</span>
<a name="l03346"></a>03346                 <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l03347"></a>03347                         __m64 mm3, mm4;
<a name="l03348"></a>03348                         mm3 = _m_punpcklbw(*mSrc1, mm0);        <span class="comment">/* unpack low  bytes of Src1 into words */</span>
<a name="l03349"></a>03349                         mm4 = _m_punpckhbw(*mSrc1, mm0);        <span class="comment">/* unpack high bytes of Src1 into words */</span>
<a name="l03350"></a>03350                         mm3 = _m_psllwi(mm3, N);                <span class="comment">/* shift 4 WORDS of MM3 (N) bits to the left */</span>
<a name="l03351"></a>03351                         mm4 = _m_psllwi(mm4, N);                <span class="comment">/* shift 4 WORDS of MM4 (N) bits to the left */</span>
<a name="l03352"></a>03352                         *mDest = _m_packuswb(mm3, mm4);         <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l03353"></a>03353                         mSrc1++;
<a name="l03354"></a>03354                         mDest++;
<a name="l03355"></a>03355                 }
<a name="l03356"></a>03356         } <span class="keywordflow">else</span> {
<a name="l03357"></a>03357                 <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l03358"></a>03358                         __m64 mm3, mm4, mm5, mm6;
<a name="l03359"></a>03359                         mm3 = _m_punpcklbw(*mSrc1, mm0);        <span class="comment">/* unpack low  bytes of Src1 into words */</span>
<a name="l03360"></a>03360                         mm4 = _m_punpckhbw(*mSrc1, mm0);        <span class="comment">/* unpack high bytes of Src1 into words */</span>
<a name="l03361"></a>03361                         mm3 = _m_psllwi(mm3, N);                <span class="comment">/* shift 4 WORDS of MM3 (N) bits to the left */</span>
<a name="l03362"></a>03362                         mm4 = _m_psllwi(mm4, N);                <span class="comment">/* shift 4 WORDS of MM4 (N) bits to the left */</span>
<a name="l03363"></a>03363                         <span class="comment">/* Take abs value of the signed words */</span>
<a name="l03364"></a>03364                         mm5 = _m_psrawi(mm3, 15);               <span class="comment">/* fill mm5 words with word sign bit */</span>
<a name="l03365"></a>03365                         mm6 = _m_psrawi(mm4, 15);               <span class="comment">/* fill mm6 words with word sign bit */</span>
<a name="l03366"></a>03366                         mm3 = _m_pxor(mm3, mm5);                <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l03367"></a>03367                         mm4 = _m_pxor(mm4, mm6);                <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l03368"></a>03368                         mm3 = _m_psubsw(mm3, mm5);              <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l03369"></a>03369                         mm4 = _m_psubsw(mm4, mm6);              <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l03370"></a>03370                         *mDest = _m_packuswb(mm3, mm4);         <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l03371"></a>03371                         mSrc1++;
<a name="l03372"></a>03372                         mDest++;
<a name="l03373"></a>03373                 }
<a name="l03374"></a>03374         }
<a name="l03375"></a>03375         _m_empty();                                             <span class="comment">/* clean MMX state */</span>
<a name="l03376"></a>03376 <span class="preprocessor">#endif</span>
<a name="l03377"></a>03377 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l03378"></a>03378 <span class="preprocessor">#else</span>
<a name="l03379"></a>03379 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l03380"></a>03380 <span class="preprocessor">#endif</span>
<a name="l03381"></a>03381 <span class="preprocessor"></span>}
<a name="l03382"></a>03382 
<a name="l03393"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a29891456dee25b30c8da8f767d7545c5">03393</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a98372fea76310903abef7808db10d226" title="Filter ShiftLeft: D = saturation255(S &lt;&lt; N)">SDL_imageFilterShiftLeft</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> N)
<a name="l03394"></a>03394 {
<a name="l03395"></a>03395         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l03396"></a>03396         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1, *curdest;
<a name="l03397"></a>03397         <span class="keywordtype">int</span> result;
<a name="l03398"></a>03398 
<a name="l03399"></a>03399         <span class="comment">/* Validate input parameters */</span>
<a name="l03400"></a>03400         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l03401"></a>03401                 <span class="keywordflow">return</span>(-1);
<a name="l03402"></a>03402         <span class="keywordflow">if</span> (length == 0)
<a name="l03403"></a>03403                 <span class="keywordflow">return</span>(0);
<a name="l03404"></a>03404 
<a name="l03405"></a>03405         <span class="keywordflow">if</span> (N &gt; 8) {
<a name="l03406"></a>03406                 <span class="keywordflow">return</span> (-1);
<a name="l03407"></a>03407         }
<a name="l03408"></a>03408 
<a name="l03409"></a>03409         <span class="comment">/* Special case: N==0 */</span>
<a name="l03410"></a>03410         <span class="keywordflow">if</span> (N == 0) {
<a name="l03411"></a>03411                 memcpy(Src1, Dest, length);
<a name="l03412"></a>03412                 <span class="keywordflow">return</span> (0); 
<a name="l03413"></a>03413         }
<a name="l03414"></a>03414 
<a name="l03415"></a>03415         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l03416"></a>03416 
<a name="l03417"></a>03417                 SDL_imageFilterShiftLeftMMX(Src1, Dest, length, N);
<a name="l03418"></a>03418 
<a name="l03419"></a>03419                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l03420"></a>03420                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l03421"></a>03421                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l03422"></a>03422                         istart = length &amp; 0xfffffff8;
<a name="l03423"></a>03423                         cursrc1 = &amp;Src1[istart];
<a name="l03424"></a>03424                         curdest = &amp;Dest[istart];
<a name="l03425"></a>03425                 } <span class="keywordflow">else</span> {
<a name="l03426"></a>03426                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l03427"></a>03427                         <span class="keywordflow">return</span> (0);
<a name="l03428"></a>03428                 }
<a name="l03429"></a>03429         } <span class="keywordflow">else</span> {
<a name="l03430"></a>03430                 <span class="comment">/* Setup to process whole image */</span>
<a name="l03431"></a>03431                 istart = 0;
<a name="l03432"></a>03432                 cursrc1 = Src1;
<a name="l03433"></a>03433                 curdest = Dest;
<a name="l03434"></a>03434         }
<a name="l03435"></a>03435 
<a name="l03436"></a>03436         <span class="comment">/* C routine to process image */</span>
<a name="l03437"></a>03437         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l03438"></a>03438                 result = (int) *cursrc1 &lt;&lt; N;
<a name="l03439"></a>03439                 <span class="keywordflow">if</span> (result &gt; 255)
<a name="l03440"></a>03440                         result = 255;
<a name="l03441"></a>03441                 *curdest = (<span class="keywordtype">unsigned</span> char) result;
<a name="l03442"></a>03442                 <span class="comment">/* Advance pointers */</span>
<a name="l03443"></a>03443                 cursrc1++;
<a name="l03444"></a>03444                 curdest++;
<a name="l03445"></a>03445         }
<a name="l03446"></a>03446 
<a name="l03447"></a>03447         <span class="keywordflow">return</span> (0);
<a name="l03448"></a>03448 }
<a name="l03449"></a>03449 
<a name="l03460"></a>03460 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterBinarizeUsingThresholdMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> T)
<a name="l03461"></a>03461 {
<a name="l03462"></a>03462 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l03463"></a>03463 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l03464"></a>03464 <span class="preprocessor"></span>        __asm
<a name="l03465"></a>03465         {
<a name="l03466"></a>03466                 pusha
<a name="l03467"></a>03467                         <span class="comment">/* ** Duplicate T in 8 bytes of MM3 ** */</span>
<a name="l03468"></a>03468                         pcmpeqb mm1, mm1        <span class="comment">/* generate all 1&#39;s in mm1 */</span>
<a name="l03469"></a>03469                         pcmpeqb mm2, mm2        <span class="comment">/* generate all 1&#39;s in mm2 */</span>
<a name="l03470"></a>03470                         mov al, T       <span class="comment">/* load T into AL */</span>
<a name="l03471"></a>03471                         mov ah, al      <span class="comment">/* copy AL into AH */</span>
<a name="l03472"></a>03472                         mov bx, ax      <span class="comment">/* copy AX into BX */</span>
<a name="l03473"></a>03473                         shl eax, 16     <span class="comment">/* shift 2 bytes of EAX left */</span>
<a name="l03474"></a>03474                         mov ax, bx      <span class="comment">/* copy BX into AX */</span>
<a name="l03475"></a>03475                         movd mm3, eax           <span class="comment">/* copy EAX into MM3 */</span>
<a name="l03476"></a>03476                         movd mm4, eax           <span class="comment">/* copy EAX into MM4 */</span>
<a name="l03477"></a>03477                         punpckldq mm3, mm4      <span class="comment">/* fill higher bytes of MM3 with T */</span>
<a name="l03478"></a>03478                         psubusb mm2, mm3        <span class="comment">/* store 0xFF - T in MM2 */</span>
<a name="l03479"></a>03479                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l03480"></a>03480                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l03481"></a>03481                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l03482"></a>03482                         shr ecx, 3      <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l03483"></a>03483                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l03484"></a>03484 L1029:
<a name="l03485"></a>03485                 movq mm0, [eax]         <span class="comment">/* load 8 bytes from SrcDest into MM0 */</span>
<a name="l03486"></a>03486                 paddusb mm0, mm2        <span class="comment">/* MM0=SrcDest+(0xFF-T) (add 8 bytes with saturation) */</span>
<a name="l03487"></a>03487                         pcmpeqb mm0, mm1        <span class="comment">/* binarize 255:0, comparing to 255 */</span>
<a name="l03488"></a>03488                         movq [edi], mm0         <span class="comment">/* store result in SrcDest */</span>
<a name="l03489"></a>03489                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l03490"></a>03490                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l03491"></a>03491                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l03492"></a>03492                         jnz             L1029           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l03493"></a>03493                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l03494"></a>03494                         popa
<a name="l03495"></a>03495         }
<a name="l03496"></a>03496 <span class="preprocessor">#else</span>
<a name="l03497"></a>03497 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l03498"></a>03498         __m64 *mSrc1 = (__m64*)Src1;
<a name="l03499"></a>03499         __m64 *mDest = (__m64*)Dest;
<a name="l03500"></a>03500         <span class="comment">/* Duplicate T in 8 bytes of MM3 */</span>
<a name="l03501"></a>03501         __m64 mm1 = _m_pcmpeqb(mm1, mm1);                       <span class="comment">/* generate all 1&#39;s in mm1 */</span>
<a name="l03502"></a>03502         __m64 mm2 = _m_pcmpeqb(mm2, mm2);                       <span class="comment">/* generate all 1&#39;s in mm1 */</span>
<a name="l03503"></a>03503         <span class="keywordtype">int</span> i;
<a name="l03504"></a>03504         memset(&amp;i, T, 4);
<a name="l03505"></a>03505         __m64 mm3 = _m_from_int(i);
<a name="l03506"></a>03506         __m64 mm4 = _m_from_int(i);
<a name="l03507"></a>03507         mm3 = _m_punpckldq(mm3, mm4);                   <span class="comment">/* fill higher bytes of MM3 with T */</span>
<a name="l03508"></a>03508         mm2 = _m_psubusb(mm2, mm3);                     <span class="comment">/* store 0xFF - T in MM2 */</span>
<a name="l03509"></a>03509         <span class="comment">//__m64 mm3 = _m_from_int64(lli); // x86_64 only</span>
<a name="l03510"></a>03510         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l03511"></a>03511                 __m64 mm0 = _m_paddusb(*mSrc1, mm2);    <span class="comment">/* Src1+(0xFF-T) (add 8 bytes with saturation) */</span>
<a name="l03512"></a>03512                 *mDest = _m_pcmpeqb(mm0, mm1);          <span class="comment">/* binarize 255:0, comparing to 255 */</span>
<a name="l03513"></a>03513                 mSrc1++;
<a name="l03514"></a>03514                 mDest++;
<a name="l03515"></a>03515         }
<a name="l03516"></a>03516         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l03517"></a>03517 <span class="preprocessor">#endif</span>
<a name="l03518"></a>03518 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l03519"></a>03519 <span class="preprocessor">#else</span>
<a name="l03520"></a>03520 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l03521"></a>03521 <span class="preprocessor">#endif</span>
<a name="l03522"></a>03522 <span class="preprocessor"></span>}
<a name="l03523"></a>03523 
<a name="l03534"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a02d89f9fa47f1f5c2d969a9d86acb041">03534</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a951a062e15df290a137428e1e0f4d5ce" title="Filter using BinarizeUsingThreshold: D = (S &gt;= T) ? 255:0.">SDL_imageFilterBinarizeUsingThreshold</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> T)
<a name="l03535"></a>03535 {
<a name="l03536"></a>03536         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l03537"></a>03537         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1;
<a name="l03538"></a>03538         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *curdest;
<a name="l03539"></a>03539 
<a name="l03540"></a>03540         <span class="comment">/* Validate input parameters */</span>
<a name="l03541"></a>03541         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l03542"></a>03542                 <span class="keywordflow">return</span>(-1);
<a name="l03543"></a>03543         <span class="keywordflow">if</span> (length == 0)
<a name="l03544"></a>03544                 <span class="keywordflow">return</span>(0);
<a name="l03545"></a>03545 
<a name="l03546"></a>03546         <span class="comment">/* Special case: T==0 */</span>
<a name="l03547"></a>03547         <span class="keywordflow">if</span> (T == 0) {
<a name="l03548"></a>03548                 memset(Dest, 255, length);
<a name="l03549"></a>03549                 <span class="keywordflow">return</span> (0); 
<a name="l03550"></a>03550         }
<a name="l03551"></a>03551 
<a name="l03552"></a>03552         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l03553"></a>03553 
<a name="l03554"></a>03554                 SDL_imageFilterBinarizeUsingThresholdMMX(Src1, Dest, length, T);
<a name="l03555"></a>03555 
<a name="l03556"></a>03556                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l03557"></a>03557                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l03558"></a>03558                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l03559"></a>03559                         istart = length &amp; 0xfffffff8;
<a name="l03560"></a>03560                         cursrc1 = &amp;Src1[istart];
<a name="l03561"></a>03561                         curdest = &amp;Dest[istart];
<a name="l03562"></a>03562                 } <span class="keywordflow">else</span> {
<a name="l03563"></a>03563                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l03564"></a>03564                         <span class="keywordflow">return</span> (0);
<a name="l03565"></a>03565                 }
<a name="l03566"></a>03566         } <span class="keywordflow">else</span> {
<a name="l03567"></a>03567                 <span class="comment">/* Setup to process whole image */</span>
<a name="l03568"></a>03568                 istart = 0;
<a name="l03569"></a>03569                 cursrc1 = Src1;
<a name="l03570"></a>03570                 curdest = Dest;
<a name="l03571"></a>03571         }
<a name="l03572"></a>03572 
<a name="l03573"></a>03573         <span class="comment">/* C routine to process image */</span>
<a name="l03574"></a>03574         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l03575"></a>03575                 *curdest = (<span class="keywordtype">unsigned</span> char)(((<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>)*cursrc1 &gt;= T) ? 255 : 0);
<a name="l03576"></a>03576                 <span class="comment">/* Advance pointers */</span>
<a name="l03577"></a>03577                 cursrc1++;
<a name="l03578"></a>03578                 curdest++;
<a name="l03579"></a>03579         }
<a name="l03580"></a>03580 
<a name="l03581"></a>03581         <span class="keywordflow">return</span> (0);
<a name="l03582"></a>03582 }
<a name="l03583"></a>03583 
<a name="l03595"></a>03595 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterClipToRangeMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Tmin,
<a name="l03596"></a>03596                                                                   <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Tmax)
<a name="l03597"></a>03597 {
<a name="l03598"></a>03598 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l03599"></a>03599 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l03600"></a>03600 <span class="preprocessor"></span>        __asm
<a name="l03601"></a>03601         {
<a name="l03602"></a>03602                 pusha
<a name="l03603"></a>03603                         pcmpeqb mm1, mm1        <span class="comment">/* generate all 1&#39;s in mm1 */</span>
<a name="l03604"></a>03604                         <span class="comment">/* ** Duplicate Tmax in 8 bytes of MM3 ** */</span>
<a name="l03605"></a>03605                         mov al, Tmax    <span class="comment">/* load Tmax into AL */</span>
<a name="l03606"></a>03606                         mov ah, al      <span class="comment">/* copy AL into AH */</span>
<a name="l03607"></a>03607                         mov bx, ax      <span class="comment">/* copy AX into BX */</span>
<a name="l03608"></a>03608                         shl eax, 16     <span class="comment">/* shift 2 bytes of EAX left */</span>
<a name="l03609"></a>03609                         mov ax, bx      <span class="comment">/* copy BX into AX */</span>
<a name="l03610"></a>03610                         movd mm3, eax           <span class="comment">/* copy EAX into MM3 */</span>
<a name="l03611"></a>03611                         movd mm4, eax           <span class="comment">/* copy EAX into MM4 */</span>
<a name="l03612"></a>03612                         punpckldq mm3, mm4      <span class="comment">/* fill higher bytes of MM3 with Tmax */</span>
<a name="l03613"></a>03613                         psubusb mm1, mm3        <span class="comment">/* store 0xFF - Tmax in MM1 */</span>
<a name="l03614"></a>03614                         <span class="comment">/* ** Duplicate Tmin in 8 bytes of MM5 ** */</span>
<a name="l03615"></a>03615                         mov al, Tmin    <span class="comment">/* load Tmin into AL */</span>
<a name="l03616"></a>03616                         mov ah, al      <span class="comment">/* copy AL into AH */</span>
<a name="l03617"></a>03617                         mov bx, ax      <span class="comment">/* copy AX into BX */</span>
<a name="l03618"></a>03618                         shl eax, 16     <span class="comment">/* shift 2 bytes of EAX left */</span>
<a name="l03619"></a>03619                         mov ax, bx      <span class="comment">/* copy BX into AX */</span>
<a name="l03620"></a>03620                         movd mm5, eax           <span class="comment">/* copy EAX into MM5 */</span>
<a name="l03621"></a>03621                         movd mm4, eax           <span class="comment">/* copy EAX into MM4 */</span>
<a name="l03622"></a>03622                         punpckldq mm5, mm4      <span class="comment">/* fill higher bytes of MM5 with Tmin */</span>
<a name="l03623"></a>03623                         movq mm7, mm5           <span class="comment">/* copy MM5 into MM7 */</span>
<a name="l03624"></a>03624                         paddusb mm7, mm1        <span class="comment">/* store 0xFF - Tmax + Tmin in MM7 */</span>
<a name="l03625"></a>03625                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l03626"></a>03626                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l03627"></a>03627                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l03628"></a>03628                         shr ecx, 3      <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l03629"></a>03629                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l03630"></a>03630 L1030:
<a name="l03631"></a>03631                 movq mm0, [eax]         <span class="comment">/* load 8 bytes from Src1 into MM0 */</span>
<a name="l03632"></a>03632                 paddusb mm0, mm1        <span class="comment">/* MM0=SrcDest+(0xFF-Tmax) */</span>
<a name="l03633"></a>03633                         psubusb mm0, mm7        <span class="comment">/* MM0=MM0-(0xFF-Tmax+Tmin) */</span>
<a name="l03634"></a>03634                         paddusb mm0, mm5        <span class="comment">/* MM0=MM0+Tmin */</span>
<a name="l03635"></a>03635                         movq [edi], mm0         <span class="comment">/* store result in Dest */</span>
<a name="l03636"></a>03636                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l03637"></a>03637                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l03638"></a>03638                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l03639"></a>03639                         jnz             L1030           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l03640"></a>03640                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l03641"></a>03641                         popa
<a name="l03642"></a>03642         }
<a name="l03643"></a>03643 <span class="preprocessor">#else</span>
<a name="l03644"></a>03644 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l03645"></a>03645         __m64 *mSrc1 = (__m64*)Src1;
<a name="l03646"></a>03646         __m64 *mDest = (__m64*)Dest;
<a name="l03647"></a>03647         __m64 mm1 = _m_pcmpeqb(mm1, mm1);       <span class="comment">/* generate all 1&#39;s in mm1 */</span>
<a name="l03648"></a>03648         <span class="keywordtype">int</span> i;
<a name="l03649"></a>03649         <span class="comment">/* Duplicate Tmax in 8 bytes of MM3 */</span>
<a name="l03650"></a>03650         __m64 mm3, mm4;
<a name="l03651"></a>03651         memset(&amp;i, Tmax, 4);
<a name="l03652"></a>03652         mm3 = _m_from_int(i);
<a name="l03653"></a>03653         mm4 = _m_from_int(i);
<a name="l03654"></a>03654         mm3 = _m_punpckldq(mm3, mm4);           <span class="comment">/* fill higher bytes of MM3 with Tmax */</span>
<a name="l03655"></a>03655         mm1 = _m_psubusb(mm1, mm3);             <span class="comment">/* store 0xFF - Tmax in MM1 */</span>
<a name="l03656"></a>03656         <span class="comment">//__m64 mm3 = _m_from_int64(lli); // x86_64 only</span>
<a name="l03657"></a>03657         <span class="comment">/* Duplicate Tmax in 8 bytes of MM3 */</span>
<a name="l03658"></a>03658         __m64 mm5, mm7;
<a name="l03659"></a>03659         memset(&amp;i, Tmin, 4);
<a name="l03660"></a>03660         mm5 = _m_from_int(i);
<a name="l03661"></a>03661         mm4 = _m_from_int(i);
<a name="l03662"></a>03662         mm5 = _m_punpckldq(mm5, mm4);           <span class="comment">/* fill higher bytes of MM5 with Tmin */</span>
<a name="l03663"></a>03663         mm7 = _m_paddusb(mm5, mm1);     <span class="comment">/* store 0xFF - Tmax + Tmin in MM7 */</span>
<a name="l03664"></a>03664         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l03665"></a>03665                 __m64 mm0;
<a name="l03666"></a>03666                 mm0 = _m_paddusb(*mSrc1, mm1);  <span class="comment">/* MM0=Src1+(0xFF-Tmax) */</span>
<a name="l03667"></a>03667                 mm0 = _m_psubusb(mm0, mm7);     <span class="comment">/* MM0=MM0-(0xFF-Tmax+Tmin) */</span>
<a name="l03668"></a>03668                 *mDest = _m_paddusb(mm0, mm5);  <span class="comment">/* MM0+Tmin */</span>
<a name="l03669"></a>03669                 mSrc1++;
<a name="l03670"></a>03670                 mDest++;
<a name="l03671"></a>03671         }
<a name="l03672"></a>03672         _m_empty();                             <span class="comment">/* clean MMX state */</span>
<a name="l03673"></a>03673 <span class="preprocessor">#endif</span>
<a name="l03674"></a>03674 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l03675"></a>03675 <span class="preprocessor">#else</span>
<a name="l03676"></a>03676 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l03677"></a>03677 <span class="preprocessor">#endif</span>
<a name="l03678"></a>03678 <span class="preprocessor"></span>}
<a name="l03679"></a>03679 
<a name="l03691"></a><a class="code" href="_s_d_l2__image_filter_8h.html#a46a5728f8857b0a06694828375527451">03691</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#ab7224abc4ecc1b8a6f4441ef8379515f" title="Filter using ClipToRange: D = (S &gt;= Tmin) &amp; (S &lt;= Tmax) S:Tmin | Tmax.">SDL_imageFilterClipToRange</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Tmin,
<a name="l03692"></a>03692                                                            <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Tmax)
<a name="l03693"></a>03693 {
<a name="l03694"></a>03694         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l03695"></a>03695         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc1;
<a name="l03696"></a>03696         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *curdest;
<a name="l03697"></a>03697 
<a name="l03698"></a>03698         <span class="comment">/* Validate input parameters */</span>
<a name="l03699"></a>03699         <span class="keywordflow">if</span> ((Src1 == NULL) || (Dest == NULL))
<a name="l03700"></a>03700                 <span class="keywordflow">return</span>(-1);
<a name="l03701"></a>03701         <span class="keywordflow">if</span> (length == 0)
<a name="l03702"></a>03702                 <span class="keywordflow">return</span>(0);
<a name="l03703"></a>03703 
<a name="l03704"></a>03704         <span class="comment">/* Special case: Tmin==0 &amp;&amp; Tmax = 255 */</span>
<a name="l03705"></a>03705         <span class="keywordflow">if</span> ((Tmin == 0) &amp;&amp; (Tmax == 25)) {
<a name="l03706"></a>03706                 memcpy(Src1, Dest, length);
<a name="l03707"></a>03707                 <span class="keywordflow">return</span> (0); 
<a name="l03708"></a>03708         }
<a name="l03709"></a>03709 
<a name="l03710"></a>03710         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l03711"></a>03711 
<a name="l03712"></a>03712                 SDL_imageFilterClipToRangeMMX(Src1, Dest, length, Tmin, Tmax);
<a name="l03713"></a>03713 
<a name="l03714"></a>03714                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l03715"></a>03715                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l03716"></a>03716                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l03717"></a>03717                         istart = length &amp; 0xfffffff8;
<a name="l03718"></a>03718                         cursrc1 = &amp;Src1[istart];
<a name="l03719"></a>03719                         curdest = &amp;Dest[istart];
<a name="l03720"></a>03720                 } <span class="keywordflow">else</span> {
<a name="l03721"></a>03721                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l03722"></a>03722                         <span class="keywordflow">return</span> (0);
<a name="l03723"></a>03723                 }
<a name="l03724"></a>03724         } <span class="keywordflow">else</span> {
<a name="l03725"></a>03725                 <span class="comment">/* Setup to process whole image */</span>
<a name="l03726"></a>03726                 istart = 0;
<a name="l03727"></a>03727                 cursrc1 = Src1;
<a name="l03728"></a>03728                 curdest = Dest;
<a name="l03729"></a>03729         }
<a name="l03730"></a>03730 
<a name="l03731"></a>03731         <span class="comment">/* C routine to process image */</span>
<a name="l03732"></a>03732         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l03733"></a>03733                 <span class="keywordflow">if</span> (*cursrc1 &lt; Tmin) {
<a name="l03734"></a>03734                         *curdest = Tmin;
<a name="l03735"></a>03735                 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (*cursrc1 &gt; Tmax) {
<a name="l03736"></a>03736                         *curdest = Tmax;
<a name="l03737"></a>03737                 } <span class="keywordflow">else</span> {
<a name="l03738"></a>03738                         *curdest = *cursrc1;
<a name="l03739"></a>03739                 }
<a name="l03740"></a>03740                 <span class="comment">/* Advance pointers */</span>
<a name="l03741"></a>03741                 cursrc1++;
<a name="l03742"></a>03742                 curdest++;
<a name="l03743"></a>03743         }
<a name="l03744"></a>03744 
<a name="l03745"></a>03745         <span class="keywordflow">return</span> (0);
<a name="l03746"></a>03746 }
<a name="l03747"></a>03747 
<a name="l03761"></a>03761 <span class="keyword">static</span> <span class="keywordtype">int</span> SDL_imageFilterNormalizeLinearMMX(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src1, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SrcLength, <span class="keywordtype">int</span> Cmin, <span class="keywordtype">int</span> Cmax,
<a name="l03762"></a>03762                                                                           <span class="keywordtype">int</span> Nmin, <span class="keywordtype">int</span> Nmax)
<a name="l03763"></a>03763 {
<a name="l03764"></a>03764 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l03765"></a>03765 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l03766"></a>03766 <span class="preprocessor"></span>        __asm
<a name="l03767"></a>03767         {
<a name="l03768"></a>03768                 pusha
<a name="l03769"></a>03769                         mov ax, WORD PTR Nmax           <span class="comment">/* load Nmax in AX */</span>
<a name="l03770"></a>03770                         mov bx, WORD PTR Cmax           <span class="comment">/* load Cmax in BX */</span>
<a name="l03771"></a>03771                         sub ax, WORD PTR Nmin           <span class="comment">/* AX = Nmax - Nmin */</span>
<a name="l03772"></a>03772                         sub bx, WORD PTR Cmin           <span class="comment">/* BX = Cmax - Cmin */</span>
<a name="l03773"></a>03773                         jz             L10311           <span class="comment">/* check division by zero */</span>
<a name="l03774"></a>03774                         xor dx, dx      <span class="comment">/* prepare for division, zero DX */</span>
<a name="l03775"></a>03775                         div               bx            <span class="comment">/* AX = AX/BX */</span>
<a name="l03776"></a>03776                         jmp            L10312
<a name="l03777"></a>03777 L10311:
<a name="l03778"></a>03778                 mov ax, 255     <span class="comment">/* if div by zero, assume result max byte value */</span>
<a name="l03779"></a>03779 L10312:                         <span class="comment">/* ** Duplicate AX in 4 words of MM0 ** */</span>
<a name="l03780"></a>03780                 mov bx, ax      <span class="comment">/* copy AX into BX */</span>
<a name="l03781"></a>03781                         shl eax, 16     <span class="comment">/* shift 2 bytes of EAX left */</span>
<a name="l03782"></a>03782                         mov ax, bx      <span class="comment">/* copy BX into AX */</span>
<a name="l03783"></a>03783                         movd mm0, eax           <span class="comment">/* copy EAX into MM0 */</span>
<a name="l03784"></a>03784                         movd mm1, eax           <span class="comment">/* copy EAX into MM1 */</span>
<a name="l03785"></a>03785                         punpckldq mm0, mm1      <span class="comment">/* fill higher words of MM0 with AX */</span>
<a name="l03786"></a>03786                         <span class="comment">/* ** Duplicate Cmin in 4 words of MM1 ** */</span>
<a name="l03787"></a>03787                         mov ax, WORD PTR Cmin           <span class="comment">/* load Cmin into AX */</span>
<a name="l03788"></a>03788                         mov bx, ax      <span class="comment">/* copy AX into BX */</span>
<a name="l03789"></a>03789                         shl eax, 16     <span class="comment">/* shift 2 bytes of EAX left */</span>
<a name="l03790"></a>03790                         mov ax, bx      <span class="comment">/* copy BX into AX */</span>
<a name="l03791"></a>03791                         movd mm1, eax           <span class="comment">/* copy EAX into MM1 */</span>
<a name="l03792"></a>03792                         movd mm2, eax           <span class="comment">/* copy EAX into MM2 */</span>
<a name="l03793"></a>03793                         punpckldq mm1, mm2      <span class="comment">/* fill higher words of MM1 with Cmin */</span>
<a name="l03794"></a>03794                         <span class="comment">/* ** Duplicate Nmin in 4 words of MM2 ** */</span>
<a name="l03795"></a>03795                         mov ax, WORD PTR Nmin           <span class="comment">/* load Nmin into AX */</span>
<a name="l03796"></a>03796                         mov bx, ax      <span class="comment">/* copy AX into BX */</span>
<a name="l03797"></a>03797                         shl eax, 16     <span class="comment">/* shift 2 bytes of EAX left */</span>
<a name="l03798"></a>03798                         mov ax, bx      <span class="comment">/* copy BX into AX */</span>
<a name="l03799"></a>03799                         movd mm2, eax           <span class="comment">/* copy EAX into MM2 */</span>
<a name="l03800"></a>03800                         movd mm3, eax           <span class="comment">/* copy EAX into MM3 */</span>
<a name="l03801"></a>03801                         punpckldq mm2, mm3      <span class="comment">/* fill higher words of MM2 with Nmin */</span>
<a name="l03802"></a>03802                         pxor mm7, mm7           <span class="comment">/* zero MM7 register */</span>
<a name="l03803"></a>03803                         mov eax, Src1           <span class="comment">/* load Src1 address into eax */</span>
<a name="l03804"></a>03804                         mov edi, Dest           <span class="comment">/* load Dest address into edi */</span>
<a name="l03805"></a>03805                         mov ecx, SrcLength      <span class="comment">/* load loop counter (SIZE) into ecx */</span>
<a name="l03806"></a>03806                         shr ecx, 3      <span class="comment">/* counter/8 (MMX loads 8 bytes at a time) */</span>
<a name="l03807"></a>03807                         align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l03808"></a>03808 L1031:
<a name="l03809"></a>03809                 movq mm3, [eax]         <span class="comment">/* load 8 bytes from Src1 into MM3 */</span>
<a name="l03810"></a>03810                 movq mm4, mm3           <span class="comment">/* copy MM3 into MM4  */</span>
<a name="l03811"></a>03811                         punpcklbw mm3, mm7      <span class="comment">/* unpack low  bytes of SrcDest into words */</span>
<a name="l03812"></a>03812                         punpckhbw mm4, mm7      <span class="comment">/* unpack high bytes of SrcDest into words */</span>
<a name="l03813"></a>03813                         psubusb mm3, mm1        <span class="comment">/* S-Cmin, low  bytes */</span>
<a name="l03814"></a>03814                         psubusb mm4, mm1        <span class="comment">/* S-Cmin, high bytes */</span>
<a name="l03815"></a>03815                         pmullw mm3, mm0         <span class="comment">/* MM0*(S-Cmin), low  bytes */</span>
<a name="l03816"></a>03816                         pmullw mm4, mm0         <span class="comment">/* MM0*(S-Cmin), high bytes */</span>
<a name="l03817"></a>03817                         paddusb mm3, mm2        <span class="comment">/* MM0*(S-Cmin)+Nmin, low  bytes */</span>
<a name="l03818"></a>03818                         paddusb mm4, mm2        <span class="comment">/* MM0*(S-Cmin)+Nmin, high bytes */</span>
<a name="l03819"></a>03819                         <span class="comment">/* ** Take abs value of the signed words ** */</span>
<a name="l03820"></a>03820                         movq mm5, mm3           <span class="comment">/* copy mm3 into mm5 */</span>
<a name="l03821"></a>03821                         movq mm6, mm4           <span class="comment">/* copy mm4 into mm6 */</span>
<a name="l03822"></a>03822                         psraw mm5, 15           <span class="comment">/* fill mm5 words with word sign bit */</span>
<a name="l03823"></a>03823                         psraw mm6, 15           <span class="comment">/* fill mm6 words with word sign bit */</span>
<a name="l03824"></a>03824                         pxor mm3, mm5           <span class="comment">/* take 1&#39;s compliment of only neg words */</span>
<a name="l03825"></a>03825                         pxor mm4, mm6           <span class="comment">/* take 1&#39;s compliment of only neg words */</span>
<a name="l03826"></a>03826                         psubsw mm3, mm5         <span class="comment">/* add 1 to only neg words, W-(-1) or W-0 */</span>
<a name="l03827"></a>03827                         psubsw mm4, mm6         <span class="comment">/* add 1 to only neg words, W-(-1) or W-0 */</span>
<a name="l03828"></a>03828                         packuswb mm3, mm4       <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l03829"></a>03829                         movq [edi], mm3         <span class="comment">/* store result in Dest */</span>
<a name="l03830"></a>03830                         add eax, 8      <span class="comment">/* increase Src1 register pointer by 8 */</span>
<a name="l03831"></a>03831                         add edi, 8      <span class="comment">/* increase Dest register pointer by 8 */</span>
<a name="l03832"></a>03832                         dec              ecx            <span class="comment">/* decrease loop counter */</span>
<a name="l03833"></a>03833                         jnz             L1031           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l03834"></a>03834                         emms                            <span class="comment">/* exit MMX state */</span>
<a name="l03835"></a>03835                         popa
<a name="l03836"></a>03836         }
<a name="l03837"></a>03837 <span class="preprocessor">#else</span>
<a name="l03838"></a>03838 <span class="preprocessor"></span>        <span class="comment">/* i386 and x86_64 */</span>
<a name="l03839"></a>03839         __m64 *mSrc1 = (__m64*)Src1;
<a name="l03840"></a>03840         __m64 *mDest = (__m64*)Dest;
<a name="l03841"></a>03841         __m64 mm0, mm1, mm2, mm3;
<a name="l03842"></a>03842 
<a name="l03843"></a>03843         <span class="keywordtype">int</span> i;
<a name="l03844"></a>03844         <span class="comment">/* Duplicate (Nmax-Nmin)/(Cmax-Cmin) in 4 words of MM0 */</span>
<a name="l03845"></a>03845         <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> a = Nmax - Nmin;
<a name="l03846"></a>03846         <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> b = Cmax - Cmin;
<a name="l03847"></a>03847         <span class="keywordflow">if</span> (b == 0) {
<a name="l03848"></a>03848             a = 255;
<a name="l03849"></a>03849         } <span class="keywordflow">else</span> {
<a name="l03850"></a>03850             a /= b;
<a name="l03851"></a>03851         }
<a name="l03852"></a>03852         i = (a&lt;&lt;16)|a;
<a name="l03853"></a>03853         mm0 = _m_from_int(i);
<a name="l03854"></a>03854         mm1 = _m_from_int(i);
<a name="l03855"></a>03855         mm0 = _m_punpckldq(mm0, mm1);                   <span class="comment">/* fill higher words of MM0 with AX */</span>
<a name="l03856"></a>03856         <span class="comment">/* Duplicate Cmin in 4 words of MM1 */</span>
<a name="l03857"></a>03857         i = (Cmin&lt;&lt;16)|(<span class="keywordtype">short</span>)Cmin;
<a name="l03858"></a>03858         mm1 = _m_from_int(i);
<a name="l03859"></a>03859         mm2 = _m_from_int(i);
<a name="l03860"></a>03860         mm1 = _m_punpckldq(mm1, mm2);                   <span class="comment">/* fill higher words of MM1 with Cmin */</span>
<a name="l03861"></a>03861         <span class="comment">/* Duplicate Nmin in 4 words of MM2 */</span>
<a name="l03862"></a>03862         i = (Nmin&lt;&lt;16)|(<span class="keywordtype">short</span>)Nmin;
<a name="l03863"></a>03863         mm2 = _m_from_int(i);
<a name="l03864"></a>03864         mm3 = _m_from_int(i);
<a name="l03865"></a>03865         mm2 = _m_punpckldq(mm2, mm3);                   <span class="comment">/* fill higher words of MM2 with Nmin */</span>
<a name="l03866"></a>03866         __m64 mm7 = _m_from_int(0);                     <span class="comment">/* zero mm0 register */</span>
<a name="l03867"></a>03867         <span class="keywordflow">for</span> (i = 0; i &lt; SrcLength/8; i++) {
<a name="l03868"></a>03868                 __m64 mm3, mm4, mm5, mm6;
<a name="l03869"></a>03869                 mm3 = _m_punpcklbw(*mSrc1, mm7);        <span class="comment">/* unpack low  bytes of Src1 into words */</span>
<a name="l03870"></a>03870                 mm4 = _m_punpckhbw(*mSrc1, mm7);        <span class="comment">/* unpack high bytes of Src1 into words */</span>
<a name="l03871"></a>03871                 mm3 = _m_psubusb(mm3, mm1);             <span class="comment">/* S-Cmin, low  bytes */</span>
<a name="l03872"></a>03872                 mm4 = _m_psubusb(mm4, mm1);             <span class="comment">/* S-Cmin, high bytes */</span>
<a name="l03873"></a>03873                 mm3 = _m_pmullw(mm3, mm0);              <span class="comment">/* MM0*(S-Cmin), low  bytes */</span>
<a name="l03874"></a>03874                 mm4 = _m_pmullw(mm4, mm0);              <span class="comment">/* MM0*(S-Cmin), high bytes */</span>
<a name="l03875"></a>03875                 mm3 = _m_paddusb(mm3, mm2);             <span class="comment">/* MM0*(S-Cmin)+Nmin, low  bytes */</span>
<a name="l03876"></a>03876                 mm4 = _m_paddusb(mm4, mm2);             <span class="comment">/* MM0*(S-Cmin)+Nmin, high bytes */</span>
<a name="l03877"></a>03877                 <span class="comment">/* Take abs value of the signed words */</span>
<a name="l03878"></a>03878                 mm5 = _m_psrawi(mm3, 15);               <span class="comment">/* fill mm5 words with word sign bit */</span>
<a name="l03879"></a>03879                 mm6 = _m_psrawi(mm4, 15);               <span class="comment">/* fill mm6 words with word sign bit */</span>
<a name="l03880"></a>03880                 mm3 = _m_pxor(mm3, mm5);                <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l03881"></a>03881                 mm4 = _m_pxor(mm4, mm6);                <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l03882"></a>03882                 mm3 = _m_psubsw(mm3, mm5);              <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l03883"></a>03883                 mm4 = _m_psubsw(mm4, mm6);              <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l03884"></a>03884                 *mDest = _m_packuswb(mm3, mm4);         <span class="comment">/* pack words back into bytes with saturation */</span>
<a name="l03885"></a>03885                 mSrc1++;
<a name="l03886"></a>03886                 mDest++;
<a name="l03887"></a>03887         }
<a name="l03888"></a>03888         _m_empty();                                     <span class="comment">/* clean MMX state */</span>
<a name="l03889"></a>03889 <span class="preprocessor">#endif</span>
<a name="l03890"></a>03890 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (0);
<a name="l03891"></a>03891 <span class="preprocessor">#else</span>
<a name="l03892"></a>03892 <span class="preprocessor"></span>        <span class="keywordflow">return</span> (-1);
<a name="l03893"></a>03893 <span class="preprocessor">#endif</span>
<a name="l03894"></a>03894 <span class="preprocessor"></span>}
<a name="l03895"></a>03895 
<a name="l03909"></a><a class="code" href="_s_d_l2__image_filter_8h.html#ade0729be518dec0b26ec164ff4e63476">03909</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#ab018ace4db884cac953b06b09c00828b" title="Filter using NormalizeLinear: D = saturation255((Nmax - Nmin)/(Cmax - Cmin)*(S - Cmin) + Nmin)...">SDL_imageFilterNormalizeLinear</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">int</span> Cmin, <span class="keywordtype">int</span> Cmax, <span class="keywordtype">int</span> Nmin,
<a name="l03910"></a>03910                                                                    <span class="keywordtype">int</span> Nmax)
<a name="l03911"></a>03911 {
<a name="l03912"></a>03912         <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, istart;
<a name="l03913"></a>03913         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *cursrc;
<a name="l03914"></a>03914         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *curdest;
<a name="l03915"></a>03915         <span class="keywordtype">int</span> dN, dC, factor;
<a name="l03916"></a>03916         <span class="keywordtype">int</span> result;
<a name="l03917"></a>03917 
<a name="l03918"></a>03918         <span class="comment">/* Validate input parameters */</span>
<a name="l03919"></a>03919         <span class="keywordflow">if</span> ((Src == NULL) || (Dest == NULL))
<a name="l03920"></a>03920                 <span class="keywordflow">return</span>(-1);
<a name="l03921"></a>03921         <span class="keywordflow">if</span> (length == 0)
<a name="l03922"></a>03922                 <span class="keywordflow">return</span>(0);
<a name="l03923"></a>03923 
<a name="l03924"></a>03924         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>()) &amp;&amp; (length &gt; 7)) {
<a name="l03925"></a>03925 
<a name="l03926"></a>03926                 SDL_imageFilterNormalizeLinearMMX(Src, Dest, length, Cmin, Cmax, Nmin, Nmax);
<a name="l03927"></a>03927 
<a name="l03928"></a>03928                 <span class="comment">/* Check for unaligned bytes */</span>
<a name="l03929"></a>03929                 <span class="keywordflow">if</span> ((length &amp; 7) &gt; 0) {
<a name="l03930"></a>03930                         <span class="comment">/* Setup to process unaligned bytes */</span>
<a name="l03931"></a>03931                         istart = length &amp; 0xfffffff8;
<a name="l03932"></a>03932                         cursrc = &amp;Src[istart];
<a name="l03933"></a>03933                         curdest = &amp;Dest[istart];
<a name="l03934"></a>03934                 } <span class="keywordflow">else</span> {
<a name="l03935"></a>03935                         <span class="comment">/* No unaligned bytes - we are done */</span>
<a name="l03936"></a>03936                         <span class="keywordflow">return</span> (0);
<a name="l03937"></a>03937                 }
<a name="l03938"></a>03938         } <span class="keywordflow">else</span> {
<a name="l03939"></a>03939                 <span class="comment">/* Setup to process whole image */</span>
<a name="l03940"></a>03940                 istart = 0;
<a name="l03941"></a>03941                 cursrc = Src;
<a name="l03942"></a>03942                 curdest = Dest;
<a name="l03943"></a>03943         }
<a name="l03944"></a>03944 
<a name="l03945"></a>03945         <span class="comment">/* C routine to process image */</span>
<a name="l03946"></a>03946         dC = Cmax - Cmin;
<a name="l03947"></a>03947         <span class="keywordflow">if</span> (dC == 0)
<a name="l03948"></a>03948                 <span class="keywordflow">return</span> (0);
<a name="l03949"></a>03949         dN = Nmax - Nmin;
<a name="l03950"></a>03950         factor = dN / dC;
<a name="l03951"></a>03951         <span class="keywordflow">for</span> (i = istart; i &lt; length; i++) {
<a name="l03952"></a>03952                 result = factor * ((int) (*cursrc) - Cmin) + Nmin;
<a name="l03953"></a>03953                 <span class="keywordflow">if</span> (result &gt; 255)
<a name="l03954"></a>03954                         result = 255;
<a name="l03955"></a>03955                 *curdest = (<span class="keywordtype">unsigned</span> char) result;
<a name="l03956"></a>03956                 <span class="comment">/* Advance pointers */</span>
<a name="l03957"></a>03957                 cursrc++;
<a name="l03958"></a>03958                 curdest++;
<a name="l03959"></a>03959         }
<a name="l03960"></a>03960 
<a name="l03961"></a>03961         <span class="keywordflow">return</span> (0);
<a name="l03962"></a>03962 }
<a name="l03963"></a>03963 
<a name="l03964"></a>03964 <span class="comment">/* ------------------------------------------------------------------------------------ */</span>
<a name="l03965"></a>03965 
<a name="l03980"></a><a class="code" href="_s_d_l2__image_filter_8c.html#a8e7e4138a93e26f1912763189d407770">03980</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a8e7e4138a93e26f1912763189d407770" title="Filter using ConvolveKernel3x3Divide: Dij = saturation0and255( ... )">SDL_imageFilterConvolveKernel3x3Divide</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">int</span> rows, <span class="keywordtype">int</span> columns,
<a name="l03981"></a>03981                                                                                    <span class="keywordtype">signed</span> <span class="keywordtype">short</span> *Kernel, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Divisor)
<a name="l03982"></a>03982 {
<a name="l03983"></a>03983         <span class="comment">/* Validate input parameters */</span>
<a name="l03984"></a>03984         <span class="keywordflow">if</span> ((Src == NULL) || (Dest == NULL) || (Kernel == NULL))
<a name="l03985"></a>03985                 <span class="keywordflow">return</span>(-1);
<a name="l03986"></a>03986 
<a name="l03987"></a>03987         <span class="keywordflow">if</span> ((columns &lt; 3) || (rows &lt; 3) || (Divisor == 0))
<a name="l03988"></a>03988                 <span class="keywordflow">return</span> (-1);
<a name="l03989"></a>03989 
<a name="l03990"></a>03990         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>())) {
<a name="l03991"></a>03991 <span class="comment">//#ifdef USE_MMX</span>
<a name="l03992"></a>03992 <span class="preprocessor">#if defined(USE_MMX) &amp;&amp; defined(i386)</span>
<a name="l03993"></a>03993 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l03994"></a>03994 <span class="preprocessor"></span>                __asm
<a name="l03995"></a>03995                 {
<a name="l03996"></a>03996                         pusha
<a name="l03997"></a>03997                                 pxor mm0, mm0           <span class="comment">/* zero MM0 */</span>
<a name="l03998"></a>03998                                 xor ebx, ebx    <span class="comment">/* zero EBX */</span>
<a name="l03999"></a>03999                                 mov bl, Divisor         <span class="comment">/* load Divisor into BL */</span>
<a name="l04000"></a>04000                                 mov edx, Kernel         <span class="comment">/* load Kernel address into EDX */</span>
<a name="l04001"></a>04001                                 movq mm5, [edx]         <span class="comment">/* MM5 = {0,K2,K1,K0} */</span>
<a name="l04002"></a>04002                         add edx, 8      <span class="comment">/* second row              |K0 K1 K2 0| */</span>
<a name="l04003"></a>04003                                 movq mm6, [edx]         <span class="comment">/* MM6 = {0,K5,K4,K3}  K = |K3 K4 K5 0| */</span>
<a name="l04004"></a>04004                         add edx, 8      <span class="comment">/* third row               |K6 K7 K8 0| */</span>
<a name="l04005"></a>04005                                 movq mm7, [edx]         <span class="comment">/* MM7 = {0,K8,K7,K6} */</span>
<a name="l04006"></a>04006                         <span class="comment">/* ---, */</span>
<a name="l04007"></a>04007                         mov eax, columns        <span class="comment">/* load columns into EAX */</span>
<a name="l04008"></a>04008                                 mov esi, Src    <span class="comment">/* ESI = Src row 0 address */</span>
<a name="l04009"></a>04009                                 mov edi, Dest           <span class="comment">/* load Dest address to EDI */</span>
<a name="l04010"></a>04010                                 add edi, eax    <span class="comment">/* EDI = EDI + columns */</span>
<a name="l04011"></a>04011                                 inc              edi            <span class="comment">/* 1 byte offset from the left edge */</span>
<a name="l04012"></a>04012                                 mov edx, rows           <span class="comment">/* initialize ROWS counter */</span>
<a name="l04013"></a>04013                                 sub edx, 2      <span class="comment">/* do not use first and last row */</span>
<a name="l04014"></a>04014                                 <span class="comment">/* ---, */</span>
<a name="l04015"></a>04015 L10320:
<a name="l04016"></a>04016                         mov ecx, eax    <span class="comment">/* initialize COLUMS counter */</span>
<a name="l04017"></a>04017                                 sub ecx, 2      <span class="comment">/* do not use first and last column */</span>
<a name="l04018"></a>04018                                 align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l04019"></a>04019 L10322:
<a name="l04020"></a>04020                         <span class="comment">/* ---, */</span>
<a name="l04021"></a>04021                         movq mm1, [esi]         <span class="comment">/* load 8 bytes of the image first row */</span>
<a name="l04022"></a>04022                         add esi, eax    <span class="comment">/* move one row below */</span>
<a name="l04023"></a>04023                                 movq mm2, [esi]         <span class="comment">/* load 8 bytes of the image second row */</span>
<a name="l04024"></a>04024                         add esi, eax    <span class="comment">/* move one row below */</span>
<a name="l04025"></a>04025                                 movq mm3, [esi]         <span class="comment">/* load 8 bytes of the image third row */</span>
<a name="l04026"></a>04026                         punpcklbw mm1, mm0      <span class="comment">/* unpack first 4 bytes into words */</span>
<a name="l04027"></a>04027                                 punpcklbw mm2, mm0      <span class="comment">/* unpack first 4 bytes into words */</span>
<a name="l04028"></a>04028                                 punpcklbw mm3, mm0      <span class="comment">/* unpack first 4 bytes into words */</span>
<a name="l04029"></a>04029                                 pmullw mm1, mm5         <span class="comment">/* multiply words first row  image*Kernel */</span>
<a name="l04030"></a>04030                                 pmullw mm2, mm6         <span class="comment">/* multiply words second row image*Kernel */</span>
<a name="l04031"></a>04031                                 pmullw mm3, mm7         <span class="comment">/* multiply words third row  image*Kernel */</span>
<a name="l04032"></a>04032                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the first and second rows */</span>
<a name="l04033"></a>04033                                 paddsw mm1, mm3         <span class="comment">/* add 4 words of the third row and result */</span>
<a name="l04034"></a>04034                                 movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04035"></a>04035                                 psrlq mm1, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l04036"></a>04036                                 paddsw mm1, mm2         <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l04037"></a>04037                                 movq mm3, mm1           <span class="comment">/* copy MM1 into MM3 */</span>
<a name="l04038"></a>04038                                 psrlq mm1, 16           <span class="comment">/* shift 1 left word to the right */</span>
<a name="l04039"></a>04039                                 paddsw mm1, mm3         <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l04040"></a>04040                                 <span class="comment">/* --, */</span>
<a name="l04041"></a>04041                                 movd mm2, eax           <span class="comment">/* save EAX in MM2 */</span>
<a name="l04042"></a>04042                                 movd mm3, edx           <span class="comment">/* save EDX in MM3 */</span>
<a name="l04043"></a>04043                                 movd eax, mm1           <span class="comment">/* copy MM1 into EAX */</span>
<a name="l04044"></a>04044                                 psraw mm1, 15           <span class="comment">/* spread sign bit of the result */</span>
<a name="l04045"></a>04045                                 movd edx, mm1           <span class="comment">/* fill EDX with a sign bit */</span>
<a name="l04046"></a>04046                                 idiv bx         <span class="comment">/* IDIV - VERY EXPENSIVE */</span>
<a name="l04047"></a>04047                                 movd mm1, eax           <span class="comment">/* move result of division into MM1 */</span>
<a name="l04048"></a>04048                                 packuswb mm1, mm0       <span class="comment">/* pack division result with saturation */</span>
<a name="l04049"></a>04049                                 movd eax, mm1           <span class="comment">/* copy saturated result into EAX */</span>
<a name="l04050"></a>04050                                 mov [edi], al           <span class="comment">/* copy a byte result into Dest */</span>
<a name="l04051"></a>04051                                 movd edx, mm3           <span class="comment">/* restore saved EDX */</span>
<a name="l04052"></a>04052                                 movd eax, mm2           <span class="comment">/* restore saved EAX */</span>
<a name="l04053"></a>04053                                 <span class="comment">/* --, */</span>
<a name="l04054"></a>04054                                 sub esi, eax    <span class="comment">/* move two rows up */</span>
<a name="l04055"></a>04055                                 sub esi, eax    <span class="comment">/* */</span>
<a name="l04056"></a>04056                                 inc              esi            <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l04057"></a>04057                                 inc              edi            <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l04058"></a>04058                                 <span class="comment">/* ---, */</span>
<a name="l04059"></a>04059                                 dec              ecx            <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l04060"></a>04060                                 jnz            L10322           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l04061"></a>04061                                 add esi, 2      <span class="comment">/* move to the next row in Src */</span>
<a name="l04062"></a>04062                                 add edi, 2      <span class="comment">/* move to the next row in Dest */</span>
<a name="l04063"></a>04063                                 dec              edx            <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l04064"></a>04064                                 jnz            L10320           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l04065"></a>04065                                 <span class="comment">/* ---, */</span>
<a name="l04066"></a>04066                                 emms                            <span class="comment">/* exit MMX state */</span>
<a name="l04067"></a>04067                                 popa
<a name="l04068"></a>04068                 }
<a name="l04069"></a>04069 <span class="preprocessor">#else</span>
<a name="l04070"></a>04070 <span class="preprocessor"></span>                <span class="keyword">asm</span> <span class="keyword">volatile</span>
<a name="l04071"></a>04071                         (<span class="stringliteral">&quot;pusha              \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm0, %%mm0 \n\t&quot;</span>        <span class="comment">/* zero MM0 */</span>
<a name="l04072"></a>04072                         <span class="stringliteral">&quot;xor       %%ebx, %%ebx \n\t&quot;</span>   <span class="comment">/* zero EBX */</span>
<a name="l04073"></a>04073                         <span class="stringliteral">&quot;mov           %5, %%bl \n\t&quot;</span>   <span class="comment">/* load Divisor into BL */</span>
<a name="l04074"></a>04074                         <span class="stringliteral">&quot;mov          %4, %%edx \n\t&quot;</span>   <span class="comment">/* load Kernel address into EDX */</span>
<a name="l04075"></a>04075                         <span class="stringliteral">&quot;movq    (%%edx), %%mm5 \n\t&quot;</span>   <span class="comment">/* MM5 = {0,K2,K1,K0} */</span>
<a name="l04076"></a>04076                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* second row              |K0 K1 K2 0| */</span>
<a name="l04077"></a>04077                         <span class="stringliteral">&quot;movq    (%%edx), %%mm6 \n\t&quot;</span>   <span class="comment">/* MM6 = {0,K5,K4,K3}  K = |K3 K4 K5 0| */</span>
<a name="l04078"></a>04078                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* third row               |K6 K7 K8 0| */</span>
<a name="l04079"></a>04079                         <span class="stringliteral">&quot;movq    (%%edx), %%mm7 \n\t&quot;</span>   <span class="comment">/* MM7 = {0,K8,K7,K6} */</span>
<a name="l04080"></a>04080                         <span class="comment">/* --- */</span>
<a name="l04081"></a>04081                         <span class="stringliteral">&quot;mov          %3, %%eax \n\t&quot;</span>   <span class="comment">/* load columns into EAX */</span>
<a name="l04082"></a>04082                         <span class="stringliteral">&quot;mov          %1, %%esi \n\t&quot;</span>   <span class="comment">/* ESI = Src row 0 address */</span>
<a name="l04083"></a>04083                         <span class="stringliteral">&quot;mov          %0, %%edi \n\t&quot;</span>   <span class="comment">/* load Dest address to EDI */</span>
<a name="l04084"></a>04084                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span>   <span class="comment">/* EDI = EDI + columns */</span>
<a name="l04085"></a>04085                         <span class="stringliteral">&quot;inc              %%edi \n\t&quot;</span>   <span class="comment">/* 1 byte offset from the left edge */</span>
<a name="l04086"></a>04086                         <span class="stringliteral">&quot;mov          %2, %%edx \n\t&quot;</span>   <span class="comment">/* initialize ROWS counter */</span>
<a name="l04087"></a>04087                         <span class="stringliteral">&quot;sub          $2, %%edx \n\t&quot;</span>   <span class="comment">/* do not use first and last row */</span>
<a name="l04088"></a>04088                         <span class="comment">/* --- */</span>
<a name="l04089"></a>04089                         <span class="stringliteral">&quot;.L10320:               \n\t&quot;</span> <span class="stringliteral">&quot;mov       %%eax, %%ecx \n\t&quot;</span>     <span class="comment">/* initialize COLUMS counter */</span>
<a name="l04090"></a>04090                         <span class="stringliteral">&quot;sub          $2, %%ecx \n\t&quot;</span>   <span class="comment">/* do not use first and last column */</span>
<a name="l04091"></a>04091                         <span class="stringliteral">&quot;.align 16              \n\t&quot;</span>   <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l04092"></a>04092                         <span class="stringliteral">&quot;.L10322:               \n\t&quot;</span>
<a name="l04093"></a>04093                         <span class="comment">/* --- */</span>
<a name="l04094"></a>04094                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the image first row */</span>
<a name="l04095"></a>04095                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move one row below */</span>
<a name="l04096"></a>04096                         <span class="stringliteral">&quot;movq    (%%esi), %%mm2 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the image second row */</span>
<a name="l04097"></a>04097                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move one row below */</span>
<a name="l04098"></a>04098                         <span class="stringliteral">&quot;movq    (%%esi), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the image third row */</span>
<a name="l04099"></a>04099                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first 4 bytes into words */</span>
<a name="l04100"></a>04100                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack first 4 bytes into words */</span>
<a name="l04101"></a>04101                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm3 \n\t&quot;</span>   <span class="comment">/* unpack first 4 bytes into words */</span>
<a name="l04102"></a>04102                         <span class="stringliteral">&quot;pmullw    %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* multiply words first row  image*Kernel */</span>
<a name="l04103"></a>04103                         <span class="stringliteral">&quot;pmullw    %%mm6, %%mm2 \n\t&quot;</span>   <span class="comment">/* multiply words second row image*Kernel */</span>
<a name="l04104"></a>04104                         <span class="stringliteral">&quot;pmullw    %%mm7, %%mm3 \n\t&quot;</span>   <span class="comment">/* multiply words third row  image*Kernel */</span>
<a name="l04105"></a>04105                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the first and second rows */</span>
<a name="l04106"></a>04106                         <span class="stringliteral">&quot;paddsw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the third row and result */</span>
<a name="l04107"></a>04107                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04108"></a>04108                         <span class="stringliteral">&quot;psrlq       $32, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l04109"></a>04109                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l04110"></a>04110                         <span class="stringliteral">&quot;movq      %%mm1, %%mm3 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM3 */</span>
<a name="l04111"></a>04111                         <span class="stringliteral">&quot;psrlq       $16, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift 1 left word to the right */</span>
<a name="l04112"></a>04112                         <span class="stringliteral">&quot;paddsw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l04113"></a>04113                         <span class="comment">/* -- */</span>
<a name="l04114"></a>04114                         <span class="stringliteral">&quot;movd      %%eax, %%mm2 \n\t&quot;</span>   <span class="comment">/* save EAX in MM2 */</span>
<a name="l04115"></a>04115                         <span class="stringliteral">&quot;movd      %%edx, %%mm3 \n\t&quot;</span>   <span class="comment">/* save EDX in MM3 */</span>
<a name="l04116"></a>04116                         <span class="stringliteral">&quot;movd      %%mm1, %%eax \n\t&quot;</span>   <span class="comment">/* copy MM1 into EAX */</span>
<a name="l04117"></a>04117                         <span class="stringliteral">&quot;psraw       $15, %%mm1 \n\t&quot;</span>   <span class="comment">/* spread sign bit of the result */</span>
<a name="l04118"></a>04118                         <span class="stringliteral">&quot;movd      %%mm1, %%edx \n\t&quot;</span>   <span class="comment">/* fill EDX with a sign bit */</span>
<a name="l04119"></a>04119                         <span class="stringliteral">&quot;idivw             %%bx \n\t&quot;</span>   <span class="comment">/* IDIV - VERY EXPENSIVE */</span>
<a name="l04120"></a>04120                         <span class="stringliteral">&quot;movd      %%eax, %%mm1 \n\t&quot;</span>   <span class="comment">/* move result of division into MM1 */</span>
<a name="l04121"></a>04121                         <span class="stringliteral">&quot;packuswb  %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* pack division result with saturation */</span>
<a name="l04122"></a>04122                         <span class="stringliteral">&quot;movd      %%mm1, %%eax \n\t&quot;</span>   <span class="comment">/* copy saturated result into EAX */</span>
<a name="l04123"></a>04123                         <span class="stringliteral">&quot;mov      %%al, (%%edi) \n\t&quot;</span>   <span class="comment">/* copy a byte result into Dest */</span>
<a name="l04124"></a>04124                         <span class="stringliteral">&quot;movd      %%mm3, %%edx \n\t&quot;</span>   <span class="comment">/* restore saved EDX */</span>
<a name="l04125"></a>04125                         <span class="stringliteral">&quot;movd      %%mm2, %%eax \n\t&quot;</span>   <span class="comment">/* restore saved EAX */</span>
<a name="l04126"></a>04126                         <span class="comment">/* -- */</span>
<a name="l04127"></a>04127                         <span class="stringliteral">&quot;sub       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move two rows up */</span>
<a name="l04128"></a>04128                         <span class="stringliteral">&quot;sub       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* */</span>
<a name="l04129"></a>04129                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l04130"></a>04130                         <span class="stringliteral">&quot;inc              %%edi \n\t&quot;</span>   <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l04131"></a>04131                         <span class="comment">/* --- */</span>
<a name="l04132"></a>04132                         <span class="stringliteral">&quot;dec              %%ecx \n\t&quot;</span>   <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l04133"></a>04133                         <span class="stringliteral">&quot;jnz            .L10322 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l04134"></a>04134                         <span class="stringliteral">&quot;add          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row in Src */</span>
<a name="l04135"></a>04135                         <span class="stringliteral">&quot;add          $2, %%edi \n\t&quot;</span>   <span class="comment">/* move to the next row in Dest */</span>
<a name="l04136"></a>04136                         <span class="stringliteral">&quot;dec              %%edx \n\t&quot;</span>   <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l04137"></a>04137                         <span class="stringliteral">&quot;jnz            .L10320 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l04138"></a>04138                         <span class="comment">/* --- */</span>
<a name="l04139"></a>04139                         <span class="stringliteral">&quot;emms                   \n\t&quot;</span>   <span class="comment">/* exit MMX state */</span>
<a name="l04140"></a>04140                         <span class="stringliteral">&quot;popa                   \n\t&quot;</span>:<span class="stringliteral">&quot;=m&quot;</span> (Dest)       <span class="comment">/* %0 */</span>
<a name="l04141"></a>04141                         :<span class="stringliteral">&quot;m&quot;</span>(Src),              <span class="comment">/* %1 */</span>
<a name="l04142"></a>04142                         <span class="stringliteral">&quot;m&quot;</span>(rows),              <span class="comment">/* %2 */</span>
<a name="l04143"></a>04143                         <span class="stringliteral">&quot;m&quot;</span>(columns),           <span class="comment">/* %3 */</span>
<a name="l04144"></a>04144                         <span class="stringliteral">&quot;m&quot;</span>(Kernel),            <span class="comment">/* %4 */</span>
<a name="l04145"></a>04145                         <span class="stringliteral">&quot;m&quot;</span>(Divisor)            <span class="comment">/* %5 */</span>
<a name="l04146"></a>04146                         );
<a name="l04147"></a>04147 <span class="preprocessor">#endif</span>
<a name="l04148"></a>04148 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l04149"></a>04149 <span class="preprocessor"></span>                <span class="keywordflow">return</span> (0);
<a name="l04150"></a>04150         } <span class="keywordflow">else</span> {
<a name="l04151"></a>04151                 <span class="comment">/* No non-MMX implementation yet */</span>
<a name="l04152"></a>04152                 <span class="keywordflow">return</span> (-1);
<a name="l04153"></a>04153         }
<a name="l04154"></a>04154 }
<a name="l04155"></a>04155 
<a name="l04170"></a><a class="code" href="_s_d_l2__image_filter_8c.html#ac9a556492480ce71f54d456a0ff7e6cb">04170</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#ac9a556492480ce71f54d456a0ff7e6cb" title="Filter using ConvolveKernel5x5Divide: Dij = saturation0and255( ... )">SDL_imageFilterConvolveKernel5x5Divide</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">int</span> rows, <span class="keywordtype">int</span> columns,
<a name="l04171"></a>04171                                                                                    <span class="keywordtype">signed</span> <span class="keywordtype">short</span> *Kernel, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Divisor)
<a name="l04172"></a>04172 {
<a name="l04173"></a>04173         <span class="comment">/* Validate input parameters */</span>
<a name="l04174"></a>04174         <span class="keywordflow">if</span> ((Src == NULL) || (Dest == NULL) || (Kernel == NULL))
<a name="l04175"></a>04175                 <span class="keywordflow">return</span>(-1);
<a name="l04176"></a>04176 
<a name="l04177"></a>04177         <span class="keywordflow">if</span> ((columns &lt; 5) || (rows &lt; 5) || (Divisor == 0))
<a name="l04178"></a>04178                 <span class="keywordflow">return</span> (-1);
<a name="l04179"></a>04179 
<a name="l04180"></a>04180         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>())) {
<a name="l04181"></a>04181 <span class="comment">//#ifdef USE_MMX</span>
<a name="l04182"></a>04182 <span class="preprocessor">#if defined(USE_MMX) &amp;&amp; defined(i386)</span>
<a name="l04183"></a>04183 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l04184"></a>04184 <span class="preprocessor"></span>                __asm
<a name="l04185"></a>04185                 {
<a name="l04186"></a>04186                         pusha
<a name="l04187"></a>04187                                 pxor mm0, mm0           <span class="comment">/* zero MM0 */</span>
<a name="l04188"></a>04188                                 xor ebx, ebx    <span class="comment">/* zero EBX */</span>
<a name="l04189"></a>04189                                 mov bl, Divisor         <span class="comment">/* load Divisor into BL */</span>
<a name="l04190"></a>04190                                 movd mm5, ebx           <span class="comment">/* copy Divisor into MM5 */</span>
<a name="l04191"></a>04191                                 mov edx, Kernel         <span class="comment">/* load Kernel address into EDX */</span>
<a name="l04192"></a>04192                                 mov esi, Src    <span class="comment">/* load Src  address to ESI */</span>
<a name="l04193"></a>04193                                 mov edi, Dest           <span class="comment">/* load Dest address to EDI */</span>
<a name="l04194"></a>04194                                 add edi, 2      <span class="comment">/* 2 column offset from the left edge */</span>
<a name="l04195"></a>04195                                 mov eax, columns        <span class="comment">/* load columns into EAX */</span>
<a name="l04196"></a>04196                                 shl eax, 1      <span class="comment">/* EAX = columns * 2 */</span>
<a name="l04197"></a>04197                                 add edi, eax    <span class="comment">/* 2 row offset from the top edge */</span>
<a name="l04198"></a>04198                                 shr eax, 1      <span class="comment">/* EAX = columns */</span>
<a name="l04199"></a>04199                                 mov ebx, rows           <span class="comment">/* initialize ROWS counter */</span>
<a name="l04200"></a>04200                                 sub ebx, 4      <span class="comment">/* do not use first 2 and last 2 rows */</span>
<a name="l04201"></a>04201                                 <span class="comment">/* ---, */</span>
<a name="l04202"></a>04202 L10330:
<a name="l04203"></a>04203                         mov ecx, eax    <span class="comment">/* initialize COLUMNS counter */</span>
<a name="l04204"></a>04204                                 sub ecx, 4      <span class="comment">/* do not use first 2 and last 2 columns */</span>
<a name="l04205"></a>04205                                 align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l04206"></a>04206 L10332:
<a name="l04207"></a>04207                         pxor mm7, mm7           <span class="comment">/* zero MM7 (accumulator) */</span>
<a name="l04208"></a>04208                                 movd mm6, esi           <span class="comment">/* save ESI in MM6 */</span>
<a name="l04209"></a>04209                                 <span class="comment">/* --- 1 */</span>
<a name="l04210"></a>04210                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04211"></a>04211                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04212"></a>04212                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04213"></a>04213                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04214"></a>04214                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04215"></a>04215                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04216"></a>04216                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04217"></a>04217                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04218"></a>04218                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04219"></a>04219                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l04220"></a>04220                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l04221"></a>04221                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04222"></a>04222                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04223"></a>04223                                 <span class="comment">/* --- 2 */</span>
<a name="l04224"></a>04224                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04225"></a>04225                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04226"></a>04226                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04227"></a>04227                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04228"></a>04228                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04229"></a>04229                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04230"></a>04230                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04231"></a>04231                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04232"></a>04232                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04233"></a>04233                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l04234"></a>04234                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l04235"></a>04235                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04236"></a>04236                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04237"></a>04237                                 <span class="comment">/* --- 3 */</span>
<a name="l04238"></a>04238                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04239"></a>04239                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04240"></a>04240                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04241"></a>04241                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04242"></a>04242                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04243"></a>04243                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04244"></a>04244                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04245"></a>04245                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04246"></a>04246                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04247"></a>04247                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l04248"></a>04248                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l04249"></a>04249                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04250"></a>04250                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04251"></a>04251                                 <span class="comment">/* --- 4 */</span>
<a name="l04252"></a>04252                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04253"></a>04253                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04254"></a>04254                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04255"></a>04255                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04256"></a>04256                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04257"></a>04257                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04258"></a>04258                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04259"></a>04259                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04260"></a>04260                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04261"></a>04261                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l04262"></a>04262                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l04263"></a>04263                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04264"></a>04264                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04265"></a>04265                                 <span class="comment">/* --- 5 */</span>
<a name="l04266"></a>04266                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04267"></a>04267                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04268"></a>04268                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04269"></a>04269                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04270"></a>04270                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04271"></a>04271                         punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04272"></a>04272                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04273"></a>04273                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l04274"></a>04274                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l04275"></a>04275                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04276"></a>04276                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04277"></a>04277                                 <span class="comment">/* ---, */</span>
<a name="l04278"></a>04278                                 movq mm3, mm7           <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l04279"></a>04279                                 psrlq mm7, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l04280"></a>04280                                 paddsw mm7, mm3         <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l04281"></a>04281                                 movq mm2, mm7           <span class="comment">/* copy MM7 into MM2 */</span>
<a name="l04282"></a>04282                                 psrlq mm7, 16           <span class="comment">/* shift 1 left word to the right */</span>
<a name="l04283"></a>04283                                 paddsw mm7, mm2         <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l04284"></a>04284                                 <span class="comment">/* ---, */</span>
<a name="l04285"></a>04285                                 movd mm1, eax           <span class="comment">/* save EDX in MM1 */</span>
<a name="l04286"></a>04286                                 movd mm2, ebx           <span class="comment">/* save EDX in MM2 */</span>
<a name="l04287"></a>04287                                 movd mm3, edx           <span class="comment">/* save EDX in MM3 */</span>
<a name="l04288"></a>04288                                 movd eax, mm7           <span class="comment">/* load summation result into EAX */</span>
<a name="l04289"></a>04289                                 psraw mm7, 15           <span class="comment">/* spread sign bit of the result */</span>
<a name="l04290"></a>04290                                 movd ebx, mm5           <span class="comment">/* load Divisor into EBX */</span>
<a name="l04291"></a>04291                                 movd edx, mm7           <span class="comment">/* fill EDX with a sign bit */</span>
<a name="l04292"></a>04292                                 idiv bx         <span class="comment">/* IDIV - VERY EXPENSIVE */</span>
<a name="l04293"></a>04293                                 movd mm7, eax           <span class="comment">/* move result of division into MM7 */</span>
<a name="l04294"></a>04294                                 packuswb mm7, mm0       <span class="comment">/* pack division result with saturation */</span>
<a name="l04295"></a>04295                                 movd eax, mm7           <span class="comment">/* copy saturated result into EAX */</span>
<a name="l04296"></a>04296                                 mov [edi], al           <span class="comment">/* copy a byte result into Dest */</span>
<a name="l04297"></a>04297                                 movd edx, mm3           <span class="comment">/* restore saved EDX */</span>
<a name="l04298"></a>04298                                 movd ebx, mm2           <span class="comment">/* restore saved EBX */</span>
<a name="l04299"></a>04299                                 movd eax, mm1           <span class="comment">/* restore saved EAX */</span>
<a name="l04300"></a>04300                                 <span class="comment">/* --, */</span>
<a name="l04301"></a>04301                                 movd esi, mm6           <span class="comment">/* move Src pointer to the top pixel */</span>
<a name="l04302"></a>04302                                 sub edx, 72     <span class="comment">/* EDX = Kernel address */</span>
<a name="l04303"></a>04303                                 inc              esi            <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l04304"></a>04304                                 inc              edi            <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l04305"></a>04305                                 <span class="comment">/* ---, */</span>
<a name="l04306"></a>04306                                 dec              ecx            <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l04307"></a>04307                                 jnz            L10332           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l04308"></a>04308                                 add esi, 4      <span class="comment">/* move to the next row in Src */</span>
<a name="l04309"></a>04309                                 add edi, 4      <span class="comment">/* move to the next row in Dest */</span>
<a name="l04310"></a>04310                                 dec              ebx            <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l04311"></a>04311                                 jnz            L10330           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l04312"></a>04312                                 <span class="comment">/* ---, */</span>
<a name="l04313"></a>04313                                 emms                            <span class="comment">/* exit MMX state */</span>
<a name="l04314"></a>04314                                 popa
<a name="l04315"></a>04315                 }
<a name="l04316"></a>04316 <span class="preprocessor">#else</span>
<a name="l04317"></a>04317 <span class="preprocessor"></span>                <span class="keyword">asm</span> <span class="keyword">volatile</span>
<a name="l04318"></a>04318                         (<span class="stringliteral">&quot;pusha              \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm0, %%mm0 \n\t&quot;</span>        <span class="comment">/* zero MM0 */</span>
<a name="l04319"></a>04319                         <span class="stringliteral">&quot;xor       %%ebx, %%ebx \n\t&quot;</span>   <span class="comment">/* zero EBX */</span>
<a name="l04320"></a>04320                         <span class="stringliteral">&quot;mov           %5, %%bl \n\t&quot;</span>   <span class="comment">/* load Divisor into BL */</span>
<a name="l04321"></a>04321                         <span class="stringliteral">&quot;movd      %%ebx, %%mm5 \n\t&quot;</span>   <span class="comment">/* copy Divisor into MM5 */</span>
<a name="l04322"></a>04322                         <span class="stringliteral">&quot;mov          %4, %%edx \n\t&quot;</span>   <span class="comment">/* load Kernel address into EDX */</span>
<a name="l04323"></a>04323                         <span class="stringliteral">&quot;mov          %1, %%esi \n\t&quot;</span>   <span class="comment">/* load Src  address to ESI */</span>
<a name="l04324"></a>04324                         <span class="stringliteral">&quot;mov          %0, %%edi \n\t&quot;</span>   <span class="comment">/* load Dest address to EDI */</span>
<a name="l04325"></a>04325                         <span class="stringliteral">&quot;add          $2, %%edi \n\t&quot;</span>   <span class="comment">/* 2 column offset from the left edge */</span>
<a name="l04326"></a>04326                         <span class="stringliteral">&quot;mov          %3, %%eax \n\t&quot;</span>   <span class="comment">/* load columns into EAX */</span>
<a name="l04327"></a>04327                         <span class="stringliteral">&quot;shl          $1, %%eax \n\t&quot;</span>   <span class="comment">/* EAX = columns * 2 */</span>
<a name="l04328"></a>04328                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span>   <span class="comment">/* 2 row offset from the top edge */</span>
<a name="l04329"></a>04329                         <span class="stringliteral">&quot;shr          $1, %%eax \n\t&quot;</span>   <span class="comment">/* EAX = columns */</span>
<a name="l04330"></a>04330                         <span class="stringliteral">&quot;mov          %2, %%ebx \n\t&quot;</span>   <span class="comment">/* initialize ROWS counter */</span>
<a name="l04331"></a>04331                         <span class="stringliteral">&quot;sub          $4, %%ebx \n\t&quot;</span>   <span class="comment">/* do not use first 2 and last 2 rows */</span>
<a name="l04332"></a>04332                         <span class="comment">/* --- */</span>
<a name="l04333"></a>04333                         <span class="stringliteral">&quot;.L10330:               \n\t&quot;</span> <span class="stringliteral">&quot;mov       %%eax, %%ecx \n\t&quot;</span>     <span class="comment">/* initialize COLUMNS counter */</span>
<a name="l04334"></a>04334                         <span class="stringliteral">&quot;sub          $4, %%ecx \n\t&quot;</span>   <span class="comment">/* do not use first 2 and last 2 columns */</span>
<a name="l04335"></a>04335                         <span class="stringliteral">&quot;.align 16              \n\t&quot;</span>   <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l04336"></a>04336                         <span class="stringliteral">&quot;.L10332:               \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm7, %%mm7 \n\t&quot;</span>     <span class="comment">/* zero MM7 (accumulator) */</span>
<a name="l04337"></a>04337                         <span class="stringliteral">&quot;movd      %%esi, %%mm6 \n\t&quot;</span>   <span class="comment">/* save ESI in MM6 */</span>
<a name="l04338"></a>04338                         <span class="comment">/* --- 1 */</span>
<a name="l04339"></a>04339                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04340"></a>04340                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04341"></a>04341                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04342"></a>04342                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04343"></a>04343                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04344"></a>04344                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04345"></a>04345                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04346"></a>04346                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04347"></a>04347                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04348"></a>04348                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04349"></a>04349                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04350"></a>04350                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04351"></a>04351                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04352"></a>04352                         <span class="comment">/* --- 2 */</span>
<a name="l04353"></a>04353                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04354"></a>04354                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04355"></a>04355                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04356"></a>04356                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04357"></a>04357                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04358"></a>04358                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04359"></a>04359                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04360"></a>04360                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04361"></a>04361                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04362"></a>04362                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04363"></a>04363                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04364"></a>04364                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04365"></a>04365                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04366"></a>04366                         <span class="comment">/* --- 3 */</span>
<a name="l04367"></a>04367                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04368"></a>04368                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04369"></a>04369                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04370"></a>04370                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04371"></a>04371                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04372"></a>04372                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04373"></a>04373                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04374"></a>04374                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04375"></a>04375                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04376"></a>04376                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04377"></a>04377                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04378"></a>04378                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04379"></a>04379                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04380"></a>04380                         <span class="comment">/* --- 4 */</span>
<a name="l04381"></a>04381                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04382"></a>04382                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04383"></a>04383                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04384"></a>04384                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04385"></a>04385                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04386"></a>04386                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04387"></a>04387                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04388"></a>04388                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04389"></a>04389                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04390"></a>04390                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04391"></a>04391                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04392"></a>04392                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04393"></a>04393                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04394"></a>04394                         <span class="comment">/* --- 5 */</span>
<a name="l04395"></a>04395                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04396"></a>04396                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04397"></a>04397                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04398"></a>04398                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04399"></a>04399                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04400"></a>04400                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04401"></a>04401                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04402"></a>04402                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04403"></a>04403                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04404"></a>04404                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04405"></a>04405                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04406"></a>04406                         <span class="comment">/* --- */</span>
<a name="l04407"></a>04407                         <span class="stringliteral">&quot;movq      %%mm7, %%mm3 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l04408"></a>04408                         <span class="stringliteral">&quot;psrlq       $32, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l04409"></a>04409                         <span class="stringliteral">&quot;paddsw    %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l04410"></a>04410                         <span class="stringliteral">&quot;movq      %%mm7, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM2 */</span>
<a name="l04411"></a>04411                         <span class="stringliteral">&quot;psrlq       $16, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 1 left word to the right */</span>
<a name="l04412"></a>04412                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l04413"></a>04413                         <span class="comment">/* --- */</span>
<a name="l04414"></a>04414                         <span class="stringliteral">&quot;movd      %%eax, %%mm1 \n\t&quot;</span>   <span class="comment">/* save EDX in MM1 */</span>
<a name="l04415"></a>04415                         <span class="stringliteral">&quot;movd      %%ebx, %%mm2 \n\t&quot;</span>   <span class="comment">/* save EDX in MM2 */</span>
<a name="l04416"></a>04416                         <span class="stringliteral">&quot;movd      %%edx, %%mm3 \n\t&quot;</span>   <span class="comment">/* save EDX in MM3 */</span>
<a name="l04417"></a>04417                         <span class="stringliteral">&quot;movd      %%mm7, %%eax \n\t&quot;</span>   <span class="comment">/* load summation result into EAX */</span>
<a name="l04418"></a>04418                         <span class="stringliteral">&quot;psraw       $15, %%mm7 \n\t&quot;</span>   <span class="comment">/* spread sign bit of the result */</span>
<a name="l04419"></a>04419                         <span class="stringliteral">&quot;movd      %%mm5, %%ebx \n\t&quot;</span>   <span class="comment">/* load Divisor into EBX */</span>
<a name="l04420"></a>04420                         <span class="stringliteral">&quot;movd      %%mm7, %%edx \n\t&quot;</span>   <span class="comment">/* fill EDX with a sign bit */</span>
<a name="l04421"></a>04421                         <span class="stringliteral">&quot;idivw             %%bx \n\t&quot;</span>   <span class="comment">/* IDIV - VERY EXPENSIVE */</span>
<a name="l04422"></a>04422                         <span class="stringliteral">&quot;movd      %%eax, %%mm7 \n\t&quot;</span>   <span class="comment">/* move result of division into MM7 */</span>
<a name="l04423"></a>04423                         <span class="stringliteral">&quot;packuswb  %%mm0, %%mm7 \n\t&quot;</span>   <span class="comment">/* pack division result with saturation */</span>
<a name="l04424"></a>04424                         <span class="stringliteral">&quot;movd      %%mm7, %%eax \n\t&quot;</span>   <span class="comment">/* copy saturated result into EAX */</span>
<a name="l04425"></a>04425                         <span class="stringliteral">&quot;mov      %%al, (%%edi) \n\t&quot;</span>   <span class="comment">/* copy a byte result into Dest */</span>
<a name="l04426"></a>04426                         <span class="stringliteral">&quot;movd      %%mm3, %%edx \n\t&quot;</span>   <span class="comment">/* restore saved EDX */</span>
<a name="l04427"></a>04427                         <span class="stringliteral">&quot;movd      %%mm2, %%ebx \n\t&quot;</span>   <span class="comment">/* restore saved EBX */</span>
<a name="l04428"></a>04428                         <span class="stringliteral">&quot;movd      %%mm1, %%eax \n\t&quot;</span>   <span class="comment">/* restore saved EAX */</span>
<a name="l04429"></a>04429                         <span class="comment">/* -- */</span>
<a name="l04430"></a>04430                         <span class="stringliteral">&quot;movd      %%mm6, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer to the top pixel */</span>
<a name="l04431"></a>04431                         <span class="stringliteral">&quot;sub         $72, %%edx \n\t&quot;</span>   <span class="comment">/* EDX = Kernel address */</span>
<a name="l04432"></a>04432                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l04433"></a>04433                         <span class="stringliteral">&quot;inc              %%edi \n\t&quot;</span>   <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l04434"></a>04434                         <span class="comment">/* --- */</span>
<a name="l04435"></a>04435                         <span class="stringliteral">&quot;dec              %%ecx \n\t&quot;</span>   <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l04436"></a>04436                         <span class="stringliteral">&quot;jnz            .L10332 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l04437"></a>04437                         <span class="stringliteral">&quot;add          $4, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row in Src */</span>
<a name="l04438"></a>04438                         <span class="stringliteral">&quot;add          $4, %%edi \n\t&quot;</span>   <span class="comment">/* move to the next row in Dest */</span>
<a name="l04439"></a>04439                         <span class="stringliteral">&quot;dec              %%ebx \n\t&quot;</span>   <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l04440"></a>04440                         <span class="stringliteral">&quot;jnz            .L10330 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l04441"></a>04441                         <span class="comment">/* --- */</span>
<a name="l04442"></a>04442                         <span class="stringliteral">&quot;emms                   \n\t&quot;</span>   <span class="comment">/* exit MMX state */</span>
<a name="l04443"></a>04443                         <span class="stringliteral">&quot;popa                   \n\t&quot;</span>:<span class="stringliteral">&quot;=m&quot;</span> (Dest)       <span class="comment">/* %0 */</span>
<a name="l04444"></a>04444                         :<span class="stringliteral">&quot;m&quot;</span>(Src),              <span class="comment">/* %1 */</span>
<a name="l04445"></a>04445                         <span class="stringliteral">&quot;m&quot;</span>(rows),              <span class="comment">/* %2 */</span>
<a name="l04446"></a>04446                         <span class="stringliteral">&quot;m&quot;</span>(columns),           <span class="comment">/* %3 */</span>
<a name="l04447"></a>04447                         <span class="stringliteral">&quot;m&quot;</span>(Kernel),            <span class="comment">/* %4 */</span>
<a name="l04448"></a>04448                         <span class="stringliteral">&quot;m&quot;</span>(Divisor)            <span class="comment">/* %5 */</span>
<a name="l04449"></a>04449                         );
<a name="l04450"></a>04450 <span class="preprocessor">#endif</span>
<a name="l04451"></a>04451 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l04452"></a>04452 <span class="preprocessor"></span>                <span class="keywordflow">return</span> (0);
<a name="l04453"></a>04453         } <span class="keywordflow">else</span> {
<a name="l04454"></a>04454                 <span class="comment">/* No non-MMX implementation yet */</span>
<a name="l04455"></a>04455                 <span class="keywordflow">return</span> (-1);
<a name="l04456"></a>04456         }
<a name="l04457"></a>04457 }
<a name="l04458"></a>04458 
<a name="l04473"></a><a class="code" href="_s_d_l2__image_filter_8c.html#a363f48e6843fd3f48da53688b89bca48">04473</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a363f48e6843fd3f48da53688b89bca48" title="Filter using ConvolveKernel7x7Divide: Dij = saturation0and255( ... )">SDL_imageFilterConvolveKernel7x7Divide</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">int</span> rows, <span class="keywordtype">int</span> columns,
<a name="l04474"></a>04474                                                                                    <span class="keywordtype">signed</span> <span class="keywordtype">short</span> *Kernel, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Divisor)
<a name="l04475"></a>04475 {
<a name="l04476"></a>04476         <span class="comment">/* Validate input parameters */</span>
<a name="l04477"></a>04477         <span class="keywordflow">if</span> ((Src == NULL) || (Dest == NULL) || (Kernel == NULL))
<a name="l04478"></a>04478                 <span class="keywordflow">return</span>(-1);
<a name="l04479"></a>04479 
<a name="l04480"></a>04480         <span class="keywordflow">if</span> ((columns &lt; 7) || (rows &lt; 7) || (Divisor == 0))
<a name="l04481"></a>04481                 <span class="keywordflow">return</span> (-1);
<a name="l04482"></a>04482 
<a name="l04483"></a>04483         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>())) {
<a name="l04484"></a>04484 <span class="comment">//#ifdef USE_MMX</span>
<a name="l04485"></a>04485 <span class="preprocessor">#if defined(USE_MMX) &amp;&amp; defined(i386)</span>
<a name="l04486"></a>04486 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l04487"></a>04487 <span class="preprocessor"></span>                __asm
<a name="l04488"></a>04488                 {
<a name="l04489"></a>04489                         pusha
<a name="l04490"></a>04490                                 pxor mm0, mm0           <span class="comment">/* zero MM0 */</span>
<a name="l04491"></a>04491                                 xor ebx, ebx    <span class="comment">/* zero EBX */</span>
<a name="l04492"></a>04492                                 mov bl, Divisor         <span class="comment">/* load Divisor into BL */</span>
<a name="l04493"></a>04493                                 movd mm5, ebx           <span class="comment">/* copy Divisor into MM5 */</span>
<a name="l04494"></a>04494                                 mov edx, Kernel         <span class="comment">/* load Kernel address into EDX */</span>
<a name="l04495"></a>04495                                 mov esi, Src    <span class="comment">/* load Src  address to ESI */</span>
<a name="l04496"></a>04496                                 mov edi, Dest           <span class="comment">/* load Dest address to EDI */</span>
<a name="l04497"></a>04497                                 add edi, 3      <span class="comment">/* 3 column offset from the left edge */</span>
<a name="l04498"></a>04498                                 mov eax, columns        <span class="comment">/* load columns into EAX */</span>
<a name="l04499"></a>04499                                 add edi, eax    <span class="comment">/* 3 row offset from the top edge */</span>
<a name="l04500"></a>04500                                 add edi, eax
<a name="l04501"></a>04501                                 add edi, eax
<a name="l04502"></a>04502                                 mov ebx, rows           <span class="comment">/* initialize ROWS counter */</span>
<a name="l04503"></a>04503                                 sub ebx, 6      <span class="comment">/* do not use first 3 and last 3 rows */</span>
<a name="l04504"></a>04504                                 <span class="comment">/* ---, */</span>
<a name="l04505"></a>04505 L10340:
<a name="l04506"></a>04506                         mov ecx, eax    <span class="comment">/* initialize COLUMNS counter */</span>
<a name="l04507"></a>04507                                 sub ecx, 6      <span class="comment">/* do not use first 3 and last 3 columns */</span>
<a name="l04508"></a>04508                                 align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l04509"></a>04509 L10342:
<a name="l04510"></a>04510                         pxor mm7, mm7           <span class="comment">/* zero MM7 (accumulator) */</span>
<a name="l04511"></a>04511                                 movd mm6, esi           <span class="comment">/* save ESI in MM6 */</span>
<a name="l04512"></a>04512                                 <span class="comment">/* --- 1 */</span>
<a name="l04513"></a>04513                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04514"></a>04514                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04515"></a>04515                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04516"></a>04516                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04517"></a>04517                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04518"></a>04518                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04519"></a>04519                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04520"></a>04520                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04521"></a>04521                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04522"></a>04522                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l04523"></a>04523                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l04524"></a>04524                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04525"></a>04525                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04526"></a>04526                                 <span class="comment">/* --- 2 */</span>
<a name="l04527"></a>04527                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04528"></a>04528                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04529"></a>04529                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04530"></a>04530                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04531"></a>04531                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04532"></a>04532                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04533"></a>04533                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04534"></a>04534                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04535"></a>04535                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04536"></a>04536                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l04537"></a>04537                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l04538"></a>04538                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04539"></a>04539                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04540"></a>04540                                 <span class="comment">/* --- 3 */</span>
<a name="l04541"></a>04541                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04542"></a>04542                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04543"></a>04543                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04544"></a>04544                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04545"></a>04545                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04546"></a>04546                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04547"></a>04547                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04548"></a>04548                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04549"></a>04549                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04550"></a>04550                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l04551"></a>04551                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l04552"></a>04552                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04553"></a>04553                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04554"></a>04554                                 <span class="comment">/* --- 4 */</span>
<a name="l04555"></a>04555                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04556"></a>04556                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04557"></a>04557                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04558"></a>04558                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04559"></a>04559                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04560"></a>04560                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04561"></a>04561                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04562"></a>04562                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04563"></a>04563                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04564"></a>04564                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l04565"></a>04565                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l04566"></a>04566                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04567"></a>04567                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04568"></a>04568                                 <span class="comment">/* --- 5 */</span>
<a name="l04569"></a>04569                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04570"></a>04570                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04571"></a>04571                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04572"></a>04572                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04573"></a>04573                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04574"></a>04574                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04575"></a>04575                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04576"></a>04576                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04577"></a>04577                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04578"></a>04578                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l04579"></a>04579                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l04580"></a>04580                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04581"></a>04581                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04582"></a>04582                                 <span class="comment">/* --- 6 */</span>
<a name="l04583"></a>04583                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04584"></a>04584                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04585"></a>04585                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04586"></a>04586                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04587"></a>04587                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04588"></a>04588                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04589"></a>04589                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04590"></a>04590                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04591"></a>04591                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04592"></a>04592                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l04593"></a>04593                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l04594"></a>04594                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04595"></a>04595                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04596"></a>04596                                 <span class="comment">/* --- 7 */</span>
<a name="l04597"></a>04597                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04598"></a>04598                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04599"></a>04599                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04600"></a>04600                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04601"></a>04601                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04602"></a>04602                         punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04603"></a>04603                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04604"></a>04604                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l04605"></a>04605                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l04606"></a>04606                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04607"></a>04607                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04608"></a>04608                                 <span class="comment">/* ---, */</span>
<a name="l04609"></a>04609                                 movq mm3, mm7           <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l04610"></a>04610                                 psrlq mm7, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l04611"></a>04611                                 paddsw mm7, mm3         <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l04612"></a>04612                                 movq mm2, mm7           <span class="comment">/* copy MM7 into MM2 */</span>
<a name="l04613"></a>04613                                 psrlq mm7, 16           <span class="comment">/* shift 1 left word to the right */</span>
<a name="l04614"></a>04614                                 paddsw mm7, mm2         <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l04615"></a>04615                                 <span class="comment">/* ---, */</span>
<a name="l04616"></a>04616                                 movd mm1, eax           <span class="comment">/* save EDX in MM1 */</span>
<a name="l04617"></a>04617                                 movd mm2, ebx           <span class="comment">/* save EDX in MM2 */</span>
<a name="l04618"></a>04618                                 movd mm3, edx           <span class="comment">/* save EDX in MM3 */</span>
<a name="l04619"></a>04619                                 movd eax, mm7           <span class="comment">/* load summation result into EAX */</span>
<a name="l04620"></a>04620                                 psraw mm7, 15           <span class="comment">/* spread sign bit of the result */</span>
<a name="l04621"></a>04621                                 movd ebx, mm5           <span class="comment">/* load Divisor into EBX */</span>
<a name="l04622"></a>04622                                 movd edx, mm7           <span class="comment">/* fill EDX with a sign bit */</span>
<a name="l04623"></a>04623                                 idiv bx         <span class="comment">/* IDIV - VERY EXPENSIVE */</span>
<a name="l04624"></a>04624                                 movd mm7, eax           <span class="comment">/* move result of division into MM7 */</span>
<a name="l04625"></a>04625                                 packuswb mm7, mm0       <span class="comment">/* pack division result with saturation */</span>
<a name="l04626"></a>04626                                 movd eax, mm7           <span class="comment">/* copy saturated result into EAX */</span>
<a name="l04627"></a>04627                                 mov [edi], al           <span class="comment">/* copy a byte result into Dest */</span>
<a name="l04628"></a>04628                                 movd edx, mm3           <span class="comment">/* restore saved EDX */</span>
<a name="l04629"></a>04629                                 movd ebx, mm2           <span class="comment">/* restore saved EBX */</span>
<a name="l04630"></a>04630                                 movd eax, mm1           <span class="comment">/* restore saved EAX */</span>
<a name="l04631"></a>04631                                 <span class="comment">/* --, */</span>
<a name="l04632"></a>04632                                 movd esi, mm6           <span class="comment">/* move Src pointer to the top pixel */</span>
<a name="l04633"></a>04633                                 sub edx, 104    <span class="comment">/* EDX = Kernel address */</span>
<a name="l04634"></a>04634                                 inc              esi            <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l04635"></a>04635                                 inc              edi            <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l04636"></a>04636                                 <span class="comment">/* ---, */</span>
<a name="l04637"></a>04637                                 dec              ecx            <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l04638"></a>04638                                 jnz            L10342           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l04639"></a>04639                                 add esi, 6      <span class="comment">/* move to the next row in Src */</span>
<a name="l04640"></a>04640                                 add edi, 6      <span class="comment">/* move to the next row in Dest */</span>
<a name="l04641"></a>04641                                 dec              ebx            <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l04642"></a>04642                                 jnz            L10340           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l04643"></a>04643                                 <span class="comment">/* ---, */</span>
<a name="l04644"></a>04644                                 emms                            <span class="comment">/* exit MMX state */</span>
<a name="l04645"></a>04645                                 popa
<a name="l04646"></a>04646                 }
<a name="l04647"></a>04647 <span class="preprocessor">#else</span>
<a name="l04648"></a>04648 <span class="preprocessor"></span>                <span class="keyword">asm</span> <span class="keyword">volatile</span>
<a name="l04649"></a>04649                         (<span class="stringliteral">&quot;pusha              \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm0, %%mm0 \n\t&quot;</span>        <span class="comment">/* zero MM0 */</span>
<a name="l04650"></a>04650                         <span class="stringliteral">&quot;xor       %%ebx, %%ebx \n\t&quot;</span>   <span class="comment">/* zero EBX */</span>
<a name="l04651"></a>04651                         <span class="stringliteral">&quot;mov           %5, %%bl \n\t&quot;</span>   <span class="comment">/* load Divisor into BL */</span>
<a name="l04652"></a>04652                         <span class="stringliteral">&quot;movd      %%ebx, %%mm5 \n\t&quot;</span>   <span class="comment">/* copy Divisor into MM5 */</span>
<a name="l04653"></a>04653                         <span class="stringliteral">&quot;mov          %4, %%edx \n\t&quot;</span>   <span class="comment">/* load Kernel address into EDX */</span>
<a name="l04654"></a>04654                         <span class="stringliteral">&quot;mov          %1, %%esi \n\t&quot;</span>   <span class="comment">/* load Src  address to ESI */</span>
<a name="l04655"></a>04655                         <span class="stringliteral">&quot;mov          %0, %%edi \n\t&quot;</span>   <span class="comment">/* load Dest address to EDI */</span>
<a name="l04656"></a>04656                         <span class="stringliteral">&quot;add          $3, %%edi \n\t&quot;</span>   <span class="comment">/* 3 column offset from the left edge */</span>
<a name="l04657"></a>04657                         <span class="stringliteral">&quot;mov          %3, %%eax \n\t&quot;</span>   <span class="comment">/* load columns into EAX */</span>
<a name="l04658"></a>04658                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span>   <span class="comment">/* 3 row offset from the top edge */</span>
<a name="l04659"></a>04659                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span> <span class="stringliteral">&quot;mov          %2, %%ebx \n\t&quot;</span>       <span class="comment">/* initialize ROWS counter */</span>
<a name="l04660"></a>04660                         <span class="stringliteral">&quot;sub          $6, %%ebx \n\t&quot;</span>   <span class="comment">/* do not use first 3 and last 3 rows */</span>
<a name="l04661"></a>04661                         <span class="comment">/* --- */</span>
<a name="l04662"></a>04662                         <span class="stringliteral">&quot;.L10340:               \n\t&quot;</span> <span class="stringliteral">&quot;mov       %%eax, %%ecx \n\t&quot;</span>     <span class="comment">/* initialize COLUMNS counter */</span>
<a name="l04663"></a>04663                         <span class="stringliteral">&quot;sub          $6, %%ecx \n\t&quot;</span>   <span class="comment">/* do not use first 3 and last 3 columns */</span>
<a name="l04664"></a>04664                         <span class="stringliteral">&quot;.align 16              \n\t&quot;</span>   <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l04665"></a>04665                         <span class="stringliteral">&quot;.L10342:               \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm7, %%mm7 \n\t&quot;</span>     <span class="comment">/* zero MM7 (accumulator) */</span>
<a name="l04666"></a>04666                         <span class="stringliteral">&quot;movd      %%esi, %%mm6 \n\t&quot;</span>   <span class="comment">/* save ESI in MM6 */</span>
<a name="l04667"></a>04667                         <span class="comment">/* --- 1 */</span>
<a name="l04668"></a>04668                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04669"></a>04669                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04670"></a>04670                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04671"></a>04671                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04672"></a>04672                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04673"></a>04673                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04674"></a>04674                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04675"></a>04675                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04676"></a>04676                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04677"></a>04677                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04678"></a>04678                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04679"></a>04679                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04680"></a>04680                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04681"></a>04681                         <span class="comment">/* --- 2 */</span>
<a name="l04682"></a>04682                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04683"></a>04683                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04684"></a>04684                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04685"></a>04685                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04686"></a>04686                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04687"></a>04687                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04688"></a>04688                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04689"></a>04689                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04690"></a>04690                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04691"></a>04691                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04692"></a>04692                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04693"></a>04693                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04694"></a>04694                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04695"></a>04695                         <span class="comment">/* --- 3 */</span>
<a name="l04696"></a>04696                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04697"></a>04697                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04698"></a>04698                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04699"></a>04699                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04700"></a>04700                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04701"></a>04701                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04702"></a>04702                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04703"></a>04703                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04704"></a>04704                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04705"></a>04705                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04706"></a>04706                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04707"></a>04707                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04708"></a>04708                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04709"></a>04709                         <span class="comment">/* --- 4 */</span>
<a name="l04710"></a>04710                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04711"></a>04711                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04712"></a>04712                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04713"></a>04713                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04714"></a>04714                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04715"></a>04715                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04716"></a>04716                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04717"></a>04717                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04718"></a>04718                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04719"></a>04719                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04720"></a>04720                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04721"></a>04721                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04722"></a>04722                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04723"></a>04723                         <span class="comment">/* --- 5 */</span>
<a name="l04724"></a>04724                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04725"></a>04725                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04726"></a>04726                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04727"></a>04727                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04728"></a>04728                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04729"></a>04729                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04730"></a>04730                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04731"></a>04731                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04732"></a>04732                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04733"></a>04733                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04734"></a>04734                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04735"></a>04735                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04736"></a>04736                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04737"></a>04737                         <span class="comment">/* --- 6 */</span>
<a name="l04738"></a>04738                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04739"></a>04739                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04740"></a>04740                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04741"></a>04741                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04742"></a>04742                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04743"></a>04743                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04744"></a>04744                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04745"></a>04745                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04746"></a>04746                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04747"></a>04747                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04748"></a>04748                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04749"></a>04749                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04750"></a>04750                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04751"></a>04751                         <span class="comment">/* --- 7 */</span>
<a name="l04752"></a>04752                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04753"></a>04753                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04754"></a>04754                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04755"></a>04755                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04756"></a>04756                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04757"></a>04757                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04758"></a>04758                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04759"></a>04759                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04760"></a>04760                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04761"></a>04761                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04762"></a>04762                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04763"></a>04763                         <span class="comment">/* --- */</span>
<a name="l04764"></a>04764                         <span class="stringliteral">&quot;movq      %%mm7, %%mm3 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l04765"></a>04765                         <span class="stringliteral">&quot;psrlq       $32, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l04766"></a>04766                         <span class="stringliteral">&quot;paddsw    %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l04767"></a>04767                         <span class="stringliteral">&quot;movq      %%mm7, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM2 */</span>
<a name="l04768"></a>04768                         <span class="stringliteral">&quot;psrlq       $16, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 1 left word to the right */</span>
<a name="l04769"></a>04769                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l04770"></a>04770                         <span class="comment">/* --- */</span>
<a name="l04771"></a>04771                         <span class="stringliteral">&quot;movd      %%eax, %%mm1 \n\t&quot;</span>   <span class="comment">/* save EDX in MM1 */</span>
<a name="l04772"></a>04772                         <span class="stringliteral">&quot;movd      %%ebx, %%mm2 \n\t&quot;</span>   <span class="comment">/* save EDX in MM2 */</span>
<a name="l04773"></a>04773                         <span class="stringliteral">&quot;movd      %%edx, %%mm3 \n\t&quot;</span>   <span class="comment">/* save EDX in MM3 */</span>
<a name="l04774"></a>04774                         <span class="stringliteral">&quot;movd      %%mm7, %%eax \n\t&quot;</span>   <span class="comment">/* load summation result into EAX */</span>
<a name="l04775"></a>04775                         <span class="stringliteral">&quot;psraw       $15, %%mm7 \n\t&quot;</span>   <span class="comment">/* spread sign bit of the result */</span>
<a name="l04776"></a>04776                         <span class="stringliteral">&quot;movd      %%mm5, %%ebx \n\t&quot;</span>   <span class="comment">/* load Divisor into EBX */</span>
<a name="l04777"></a>04777                         <span class="stringliteral">&quot;movd      %%mm7, %%edx \n\t&quot;</span>   <span class="comment">/* fill EDX with a sign bit */</span>
<a name="l04778"></a>04778                         <span class="stringliteral">&quot;idivw             %%bx \n\t&quot;</span>   <span class="comment">/* IDIV - VERY EXPENSIVE */</span>
<a name="l04779"></a>04779                         <span class="stringliteral">&quot;movd      %%eax, %%mm7 \n\t&quot;</span>   <span class="comment">/* move result of division into MM7 */</span>
<a name="l04780"></a>04780                         <span class="stringliteral">&quot;packuswb  %%mm0, %%mm7 \n\t&quot;</span>   <span class="comment">/* pack division result with saturation */</span>
<a name="l04781"></a>04781                         <span class="stringliteral">&quot;movd      %%mm7, %%eax \n\t&quot;</span>   <span class="comment">/* copy saturated result into EAX */</span>
<a name="l04782"></a>04782                         <span class="stringliteral">&quot;mov      %%al, (%%edi) \n\t&quot;</span>   <span class="comment">/* copy a byte result into Dest */</span>
<a name="l04783"></a>04783                         <span class="stringliteral">&quot;movd      %%mm3, %%edx \n\t&quot;</span>   <span class="comment">/* restore saved EDX */</span>
<a name="l04784"></a>04784                         <span class="stringliteral">&quot;movd      %%mm2, %%ebx \n\t&quot;</span>   <span class="comment">/* restore saved EBX */</span>
<a name="l04785"></a>04785                         <span class="stringliteral">&quot;movd      %%mm1, %%eax \n\t&quot;</span>   <span class="comment">/* restore saved EAX */</span>
<a name="l04786"></a>04786                         <span class="comment">/* -- */</span>
<a name="l04787"></a>04787                         <span class="stringliteral">&quot;movd      %%mm6, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer to the top pixel */</span>
<a name="l04788"></a>04788                         <span class="stringliteral">&quot;sub        $104, %%edx \n\t&quot;</span>   <span class="comment">/* EDX = Kernel address */</span>
<a name="l04789"></a>04789                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l04790"></a>04790                         <span class="stringliteral">&quot;inc              %%edi \n\t&quot;</span>   <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l04791"></a>04791                         <span class="comment">/* --- */</span>
<a name="l04792"></a>04792                         <span class="stringliteral">&quot;dec              %%ecx \n\t&quot;</span>   <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l04793"></a>04793                         <span class="stringliteral">&quot;jnz            .L10342 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l04794"></a>04794                         <span class="stringliteral">&quot;add          $6, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row in Src */</span>
<a name="l04795"></a>04795                         <span class="stringliteral">&quot;add          $6, %%edi \n\t&quot;</span>   <span class="comment">/* move to the next row in Dest */</span>
<a name="l04796"></a>04796                         <span class="stringliteral">&quot;dec              %%ebx \n\t&quot;</span>   <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l04797"></a>04797                         <span class="stringliteral">&quot;jnz            .L10340 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l04798"></a>04798                         <span class="comment">/* --- */</span>
<a name="l04799"></a>04799                         <span class="stringliteral">&quot;emms                   \n\t&quot;</span>   <span class="comment">/* exit MMX state */</span>
<a name="l04800"></a>04800                         <span class="stringliteral">&quot;popa                   \n\t&quot;</span>:<span class="stringliteral">&quot;=m&quot;</span> (Dest)       <span class="comment">/* %0 */</span>
<a name="l04801"></a>04801                         :<span class="stringliteral">&quot;m&quot;</span>(Src),              <span class="comment">/* %1 */</span>
<a name="l04802"></a>04802                         <span class="stringliteral">&quot;m&quot;</span>(rows),              <span class="comment">/* %2 */</span>
<a name="l04803"></a>04803                         <span class="stringliteral">&quot;m&quot;</span>(columns),           <span class="comment">/* %3 */</span>
<a name="l04804"></a>04804                         <span class="stringliteral">&quot;m&quot;</span>(Kernel),            <span class="comment">/* %4 */</span>
<a name="l04805"></a>04805                         <span class="stringliteral">&quot;m&quot;</span>(Divisor)            <span class="comment">/* %5 */</span>
<a name="l04806"></a>04806                         );
<a name="l04807"></a>04807 <span class="preprocessor">#endif</span>
<a name="l04808"></a>04808 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l04809"></a>04809 <span class="preprocessor"></span>                <span class="keywordflow">return</span> (0);
<a name="l04810"></a>04810         } <span class="keywordflow">else</span> {
<a name="l04811"></a>04811                 <span class="comment">/* No non-MMX implementation yet */</span>
<a name="l04812"></a>04812                 <span class="keywordflow">return</span> (-1);
<a name="l04813"></a>04813         }
<a name="l04814"></a>04814 }
<a name="l04815"></a>04815 
<a name="l04830"></a><a class="code" href="_s_d_l2__image_filter_8c.html#ae1e91ff193beed110a71119ec901f09d">04830</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#ae1e91ff193beed110a71119ec901f09d" title="Filter using ConvolveKernel9x9Divide: Dij = saturation0and255( ... )">SDL_imageFilterConvolveKernel9x9Divide</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">int</span> rows, <span class="keywordtype">int</span> columns,
<a name="l04831"></a>04831                                                                                    <span class="keywordtype">signed</span> <span class="keywordtype">short</span> *Kernel, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Divisor)
<a name="l04832"></a>04832 {
<a name="l04833"></a>04833         <span class="comment">/* Validate input parameters */</span>
<a name="l04834"></a>04834         <span class="keywordflow">if</span> ((Src == NULL) || (Dest == NULL) || (Kernel == NULL))
<a name="l04835"></a>04835                 <span class="keywordflow">return</span>(-1);
<a name="l04836"></a>04836 
<a name="l04837"></a>04837         <span class="keywordflow">if</span> ((columns &lt; 9) || (rows &lt; 9) || (Divisor == 0))
<a name="l04838"></a>04838                 <span class="keywordflow">return</span> (-1);
<a name="l04839"></a>04839 
<a name="l04840"></a>04840         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>())) {
<a name="l04841"></a>04841 <span class="comment">//#ifdef USE_MMX</span>
<a name="l04842"></a>04842 <span class="preprocessor">#if defined(USE_MMX) &amp;&amp; defined(i386)</span>
<a name="l04843"></a>04843 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l04844"></a>04844 <span class="preprocessor"></span>                __asm
<a name="l04845"></a>04845                 {
<a name="l04846"></a>04846                         pusha
<a name="l04847"></a>04847                                 pxor mm0, mm0           <span class="comment">/* zero MM0 */</span>
<a name="l04848"></a>04848                                 xor ebx, ebx    <span class="comment">/* zero EBX */</span>
<a name="l04849"></a>04849                                 mov bl, Divisor         <span class="comment">/* load Divisor into BL */</span>
<a name="l04850"></a>04850                                 movd mm5, ebx           <span class="comment">/* copy Divisor into MM5 */</span>
<a name="l04851"></a>04851                                 mov edx, Kernel         <span class="comment">/* load Kernel address into EDX */</span>
<a name="l04852"></a>04852                                 mov esi, Src    <span class="comment">/* load Src  address to ESI */</span>
<a name="l04853"></a>04853                                 mov edi, Dest           <span class="comment">/* load Dest address to EDI */</span>
<a name="l04854"></a>04854                                 add edi, 4      <span class="comment">/* 4 column offset from the left edge */</span>
<a name="l04855"></a>04855                                 mov eax, columns        <span class="comment">/* load columns into EAX */</span>
<a name="l04856"></a>04856                                 add edi, eax    <span class="comment">/* 4 row offset from the top edge */</span>
<a name="l04857"></a>04857                                 add edi, eax
<a name="l04858"></a>04858                                 add edi, eax
<a name="l04859"></a>04859                                 add edi, eax
<a name="l04860"></a>04860                                 mov ebx, rows           <span class="comment">/* initialize ROWS counter */</span>
<a name="l04861"></a>04861                                 sub ebx, 8      <span class="comment">/* do not use first 4 and last 4 rows */</span>
<a name="l04862"></a>04862                                 <span class="comment">/* ---, */</span>
<a name="l04863"></a>04863 L10350:
<a name="l04864"></a>04864                         mov ecx, eax    <span class="comment">/* initialize COLUMNS counter */</span>
<a name="l04865"></a>04865                                 sub ecx, 8      <span class="comment">/* do not use first 4 and last 4 columns */</span>
<a name="l04866"></a>04866                                 align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l04867"></a>04867 L10352:
<a name="l04868"></a>04868                         pxor mm7, mm7           <span class="comment">/* zero MM7 (accumulator) */</span>
<a name="l04869"></a>04869                                 movd mm6, esi           <span class="comment">/* save ESI in MM6 */</span>
<a name="l04870"></a>04870                                 <span class="comment">/* --- 1 */</span>
<a name="l04871"></a>04871                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04872"></a>04872                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04873"></a>04873                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l04874"></a>04874                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04875"></a>04875                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04876"></a>04876                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04877"></a>04877                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04878"></a>04878                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04879"></a>04879                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04880"></a>04880                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04881"></a>04881                                 pmullw mm2, mm4         <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04882"></a>04882                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04883"></a>04883                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04884"></a>04884                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04885"></a>04885                         dec              esi
<a name="l04886"></a>04886                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04887"></a>04887                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04888"></a>04888                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04889"></a>04889                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04890"></a>04890                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04891"></a>04891                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04892"></a>04892                                 <span class="comment">/* --- 2 */</span>
<a name="l04893"></a>04893                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04894"></a>04894                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04895"></a>04895                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l04896"></a>04896                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04897"></a>04897                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04898"></a>04898                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04899"></a>04899                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04900"></a>04900                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04901"></a>04901                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04902"></a>04902                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04903"></a>04903                                 pmullw mm2, mm4         <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04904"></a>04904                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04905"></a>04905                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04906"></a>04906                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04907"></a>04907                         dec              esi
<a name="l04908"></a>04908                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04909"></a>04909                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04910"></a>04910                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04911"></a>04911                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04912"></a>04912                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04913"></a>04913                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04914"></a>04914                                 <span class="comment">/* --- 3 */</span>
<a name="l04915"></a>04915                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04916"></a>04916                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04917"></a>04917                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l04918"></a>04918                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04919"></a>04919                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04920"></a>04920                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04921"></a>04921                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04922"></a>04922                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04923"></a>04923                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04924"></a>04924                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04925"></a>04925                                 pmullw mm2, mm4         <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04926"></a>04926                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04927"></a>04927                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04928"></a>04928                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04929"></a>04929                         dec              esi
<a name="l04930"></a>04930                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04931"></a>04931                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04932"></a>04932                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04933"></a>04933                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04934"></a>04934                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04935"></a>04935                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04936"></a>04936                                 <span class="comment">/* --- 4 */</span>
<a name="l04937"></a>04937                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04938"></a>04938                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04939"></a>04939                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l04940"></a>04940                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04941"></a>04941                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04942"></a>04942                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04943"></a>04943                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04944"></a>04944                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04945"></a>04945                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04946"></a>04946                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04947"></a>04947                                 pmullw mm2, mm4         <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04948"></a>04948                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04949"></a>04949                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04950"></a>04950                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04951"></a>04951                         dec              esi
<a name="l04952"></a>04952                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04953"></a>04953                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04954"></a>04954                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04955"></a>04955                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04956"></a>04956                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04957"></a>04957                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04958"></a>04958                                 <span class="comment">/* --- 5 */</span>
<a name="l04959"></a>04959                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04960"></a>04960                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04961"></a>04961                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l04962"></a>04962                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04963"></a>04963                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04964"></a>04964                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04965"></a>04965                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04966"></a>04966                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04967"></a>04967                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04968"></a>04968                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04969"></a>04969                                 pmullw mm2, mm4         <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04970"></a>04970                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04971"></a>04971                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04972"></a>04972                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04973"></a>04973                         dec              esi
<a name="l04974"></a>04974                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04975"></a>04975                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04976"></a>04976                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04977"></a>04977                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04978"></a>04978                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04979"></a>04979                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04980"></a>04980                                 <span class="comment">/* --- 6 */</span>
<a name="l04981"></a>04981                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04982"></a>04982                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l04983"></a>04983                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l04984"></a>04984                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04985"></a>04985                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04986"></a>04986                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04987"></a>04987                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04988"></a>04988                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l04989"></a>04989                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l04990"></a>04990                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l04991"></a>04991                                 pmullw mm2, mm4         <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l04992"></a>04992                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l04993"></a>04993                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l04994"></a>04994                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l04995"></a>04995                         dec              esi
<a name="l04996"></a>04996                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l04997"></a>04997                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l04998"></a>04998                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l04999"></a>04999                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05000"></a>05000                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05001"></a>05001                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05002"></a>05002                                 <span class="comment">/* --- 7 */</span>
<a name="l05003"></a>05003                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05004"></a>05004                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05005"></a>05005                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l05006"></a>05006                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05007"></a>05007                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05008"></a>05008                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05009"></a>05009                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05010"></a>05010                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05011"></a>05011                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05012"></a>05012                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05013"></a>05013                                 pmullw mm2, mm4         <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05014"></a>05014                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05015"></a>05015                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05016"></a>05016                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05017"></a>05017                         dec              esi
<a name="l05018"></a>05018                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05019"></a>05019                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05020"></a>05020                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05021"></a>05021                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05022"></a>05022                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05023"></a>05023                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05024"></a>05024                                 <span class="comment">/* --- 8 */</span>
<a name="l05025"></a>05025                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05026"></a>05026                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05027"></a>05027                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l05028"></a>05028                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05029"></a>05029                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05030"></a>05030                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05031"></a>05031                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05032"></a>05032                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05033"></a>05033                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05034"></a>05034                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05035"></a>05035                                 pmullw mm2, mm4         <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05036"></a>05036                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05037"></a>05037                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05038"></a>05038                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05039"></a>05039                         dec              esi
<a name="l05040"></a>05040                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05041"></a>05041                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05042"></a>05042                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05043"></a>05043                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05044"></a>05044                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05045"></a>05045                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05046"></a>05046                                 <span class="comment">/* --- 9 */</span>
<a name="l05047"></a>05047                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05048"></a>05048                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05049"></a>05049                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l05050"></a>05050                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05051"></a>05051                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05052"></a>05052                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05053"></a>05053                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05054"></a>05054                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05055"></a>05055                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05056"></a>05056                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05057"></a>05057                                 pmullw mm2, mm4         <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05058"></a>05058                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05059"></a>05059                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05060"></a>05060                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05061"></a>05061                         movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05062"></a>05062                         punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05063"></a>05063                                 pmullw mm1, mm3         <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05064"></a>05064                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05065"></a>05065                                 <span class="comment">/* ---, */</span>
<a name="l05066"></a>05066                                 movq mm3, mm7           <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l05067"></a>05067                                 psrlq mm7, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l05068"></a>05068                                 paddsw mm7, mm3         <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l05069"></a>05069                                 movq mm2, mm7           <span class="comment">/* copy MM7 into MM2 */</span>
<a name="l05070"></a>05070                                 psrlq mm7, 16           <span class="comment">/* shift 1 left word to the right */</span>
<a name="l05071"></a>05071                                 paddsw mm7, mm2         <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l05072"></a>05072                                 <span class="comment">/* ---, */</span>
<a name="l05073"></a>05073                                 movd mm1, eax           <span class="comment">/* save EDX in MM1 */</span>
<a name="l05074"></a>05074                                 movd mm2, ebx           <span class="comment">/* save EDX in MM2 */</span>
<a name="l05075"></a>05075                                 movd mm3, edx           <span class="comment">/* save EDX in MM3 */</span>
<a name="l05076"></a>05076                                 movd eax, mm7           <span class="comment">/* load summation result into EAX */</span>
<a name="l05077"></a>05077                                 psraw mm7, 15           <span class="comment">/* spread sign bit of the result */</span>
<a name="l05078"></a>05078                                 movd ebx, mm5           <span class="comment">/* load Divisor into EBX */</span>
<a name="l05079"></a>05079                                 movd edx, mm7           <span class="comment">/* fill EDX with a sign bit */</span>
<a name="l05080"></a>05080                                 idiv bx         <span class="comment">/* IDIV - VERY EXPENSIVE */</span>
<a name="l05081"></a>05081                                 movd mm7, eax           <span class="comment">/* move result of division into MM7 */</span>
<a name="l05082"></a>05082                                 packuswb mm7, mm0       <span class="comment">/* pack division result with saturation */</span>
<a name="l05083"></a>05083                                 movd eax, mm7           <span class="comment">/* copy saturated result into EAX */</span>
<a name="l05084"></a>05084                                 mov [edi], al           <span class="comment">/* copy a byte result into Dest */</span>
<a name="l05085"></a>05085                                 movd edx, mm3           <span class="comment">/* restore saved EDX */</span>
<a name="l05086"></a>05086                                 movd ebx, mm2           <span class="comment">/* restore saved EBX */</span>
<a name="l05087"></a>05087                                 movd eax, mm1           <span class="comment">/* restore saved EAX */</span>
<a name="l05088"></a>05088                                 <span class="comment">/* --, */</span>
<a name="l05089"></a>05089                                 movd esi, mm6           <span class="comment">/* move Src pointer to the top pixel */</span>
<a name="l05090"></a>05090                                 sub edx, 208    <span class="comment">/* EDX = Kernel address */</span>
<a name="l05091"></a>05091                                 inc              esi            <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l05092"></a>05092                                 inc              edi            <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l05093"></a>05093                                 <span class="comment">/* ---, */</span>
<a name="l05094"></a>05094                                 dec              ecx            <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l05095"></a>05095                                 jnz            L10352           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l05096"></a>05096                                 add esi, 8      <span class="comment">/* move to the next row in Src */</span>
<a name="l05097"></a>05097                                 add edi, 8      <span class="comment">/* move to the next row in Dest */</span>
<a name="l05098"></a>05098                                 dec              ebx            <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l05099"></a>05099                                 jnz            L10350           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l05100"></a>05100                                 <span class="comment">/* ---, */</span>
<a name="l05101"></a>05101                                 emms                            <span class="comment">/* exit MMX state */</span>
<a name="l05102"></a>05102                                 popa
<a name="l05103"></a>05103                 }
<a name="l05104"></a>05104 <span class="preprocessor">#else</span>
<a name="l05105"></a>05105 <span class="preprocessor"></span>                <span class="keyword">asm</span> <span class="keyword">volatile</span>
<a name="l05106"></a>05106                         (<span class="stringliteral">&quot;pusha              \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm0, %%mm0 \n\t&quot;</span>        <span class="comment">/* zero MM0 */</span>
<a name="l05107"></a>05107                         <span class="stringliteral">&quot;xor       %%ebx, %%ebx \n\t&quot;</span>   <span class="comment">/* zero EBX */</span>
<a name="l05108"></a>05108                         <span class="stringliteral">&quot;mov           %5, %%bl \n\t&quot;</span>   <span class="comment">/* load Divisor into BL */</span>
<a name="l05109"></a>05109                         <span class="stringliteral">&quot;movd      %%ebx, %%mm5 \n\t&quot;</span>   <span class="comment">/* copy Divisor into MM5 */</span>
<a name="l05110"></a>05110                         <span class="stringliteral">&quot;mov          %4, %%edx \n\t&quot;</span>   <span class="comment">/* load Kernel address into EDX */</span>
<a name="l05111"></a>05111                         <span class="stringliteral">&quot;mov          %1, %%esi \n\t&quot;</span>   <span class="comment">/* load Src  address to ESI */</span>
<a name="l05112"></a>05112                         <span class="stringliteral">&quot;mov          %0, %%edi \n\t&quot;</span>   <span class="comment">/* load Dest address to EDI */</span>
<a name="l05113"></a>05113                         <span class="stringliteral">&quot;add          $4, %%edi \n\t&quot;</span>   <span class="comment">/* 4 column offset from the left edge */</span>
<a name="l05114"></a>05114                         <span class="stringliteral">&quot;mov          %3, %%eax \n\t&quot;</span>   <span class="comment">/* load columns into EAX */</span>
<a name="l05115"></a>05115                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span>   <span class="comment">/* 4 row offset from the top edge */</span>
<a name="l05116"></a>05116                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span> <span class="stringliteral">&quot;mov          %2, %%ebx \n\t&quot;</span> <span class="comment">/* initialize ROWS counter */</span>
<a name="l05117"></a>05117                         <span class="stringliteral">&quot;sub          $8, %%ebx \n\t&quot;</span>   <span class="comment">/* do not use first 4 and last 4 rows */</span>
<a name="l05118"></a>05118                         <span class="comment">/* --- */</span>
<a name="l05119"></a>05119                         <span class="stringliteral">&quot;.L10350:               \n\t&quot;</span> <span class="stringliteral">&quot;mov       %%eax, %%ecx \n\t&quot;</span>     <span class="comment">/* initialize COLUMNS counter */</span>
<a name="l05120"></a>05120                         <span class="stringliteral">&quot;sub          $8, %%ecx \n\t&quot;</span>   <span class="comment">/* do not use first 4 and last 4 columns */</span>
<a name="l05121"></a>05121                         <span class="stringliteral">&quot;.align 16              \n\t&quot;</span>   <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l05122"></a>05122                         <span class="stringliteral">&quot;.L10352:               \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm7, %%mm7 \n\t&quot;</span>     <span class="comment">/* zero MM7 (accumulator) */</span>
<a name="l05123"></a>05123                         <span class="stringliteral">&quot;movd      %%esi, %%mm6 \n\t&quot;</span>   <span class="comment">/* save ESI in MM6 */</span>
<a name="l05124"></a>05124                         <span class="comment">/* --- 1 */</span>
<a name="l05125"></a>05125                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05126"></a>05126                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05127"></a>05127                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l05128"></a>05128                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05129"></a>05129                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05130"></a>05130                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05131"></a>05131                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05132"></a>05132                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05133"></a>05133                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05134"></a>05134                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05135"></a>05135                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05136"></a>05136                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05137"></a>05137                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05138"></a>05138                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05139"></a>05139                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05140"></a>05140                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05141"></a>05141                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05142"></a>05142                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05143"></a>05143                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05144"></a>05144                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05145"></a>05145                         <span class="comment">/* --- 2 */</span>
<a name="l05146"></a>05146                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05147"></a>05147                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05148"></a>05148                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l05149"></a>05149                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05150"></a>05150                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05151"></a>05151                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05152"></a>05152                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05153"></a>05153                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05154"></a>05154                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05155"></a>05155                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05156"></a>05156                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05157"></a>05157                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05158"></a>05158                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05159"></a>05159                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05160"></a>05160                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05161"></a>05161                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05162"></a>05162                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05163"></a>05163                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05164"></a>05164                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05165"></a>05165                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05166"></a>05166                         <span class="comment">/* --- 3 */</span>
<a name="l05167"></a>05167                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05168"></a>05168                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05169"></a>05169                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l05170"></a>05170                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05171"></a>05171                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05172"></a>05172                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05173"></a>05173                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05174"></a>05174                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05175"></a>05175                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05176"></a>05176                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05177"></a>05177                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05178"></a>05178                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05179"></a>05179                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05180"></a>05180                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05181"></a>05181                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05182"></a>05182                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05183"></a>05183                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05184"></a>05184                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05185"></a>05185                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05186"></a>05186                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05187"></a>05187                         <span class="comment">/* --- 4 */</span>
<a name="l05188"></a>05188                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05189"></a>05189                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05190"></a>05190                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l05191"></a>05191                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05192"></a>05192                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05193"></a>05193                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05194"></a>05194                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05195"></a>05195                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05196"></a>05196                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05197"></a>05197                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05198"></a>05198                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05199"></a>05199                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05200"></a>05200                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05201"></a>05201                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05202"></a>05202                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05203"></a>05203                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05204"></a>05204                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05205"></a>05205                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05206"></a>05206                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05207"></a>05207                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05208"></a>05208                         <span class="comment">/* --- 5 */</span>
<a name="l05209"></a>05209                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05210"></a>05210                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05211"></a>05211                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l05212"></a>05212                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05213"></a>05213                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05214"></a>05214                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05215"></a>05215                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05216"></a>05216                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05217"></a>05217                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05218"></a>05218                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05219"></a>05219                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05220"></a>05220                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05221"></a>05221                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05222"></a>05222                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05223"></a>05223                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05224"></a>05224                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05225"></a>05225                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05226"></a>05226                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05227"></a>05227                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05228"></a>05228                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05229"></a>05229                         <span class="comment">/* --- 6 */</span>
<a name="l05230"></a>05230                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05231"></a>05231                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05232"></a>05232                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l05233"></a>05233                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05234"></a>05234                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05235"></a>05235                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05236"></a>05236                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05237"></a>05237                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05238"></a>05238                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05239"></a>05239                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05240"></a>05240                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05241"></a>05241                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05242"></a>05242                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05243"></a>05243                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05244"></a>05244                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05245"></a>05245                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05246"></a>05246                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05247"></a>05247                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05248"></a>05248                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05249"></a>05249                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05250"></a>05250                         <span class="comment">/* --- 7 */</span>
<a name="l05251"></a>05251                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05252"></a>05252                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05253"></a>05253                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l05254"></a>05254                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05255"></a>05255                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05256"></a>05256                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05257"></a>05257                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05258"></a>05258                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05259"></a>05259                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05260"></a>05260                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05261"></a>05261                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05262"></a>05262                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05263"></a>05263                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05264"></a>05264                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05265"></a>05265                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05266"></a>05266                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05267"></a>05267                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05268"></a>05268                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05269"></a>05269                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05270"></a>05270                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05271"></a>05271                         <span class="comment">/* --- 8 */</span>
<a name="l05272"></a>05272                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05273"></a>05273                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05274"></a>05274                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l05275"></a>05275                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05276"></a>05276                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05277"></a>05277                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05278"></a>05278                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05279"></a>05279                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05280"></a>05280                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05281"></a>05281                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05282"></a>05282                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05283"></a>05283                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05284"></a>05284                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05285"></a>05285                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05286"></a>05286                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05287"></a>05287                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05288"></a>05288                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05289"></a>05289                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05290"></a>05290                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05291"></a>05291                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05292"></a>05292                         <span class="comment">/* --- 9 */</span>
<a name="l05293"></a>05293                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05294"></a>05294                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05295"></a>05295                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l05296"></a>05296                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05297"></a>05297                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05298"></a>05298                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05299"></a>05299                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05300"></a>05300                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05301"></a>05301                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05302"></a>05302                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05303"></a>05303                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05304"></a>05304                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05305"></a>05305                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05306"></a>05306                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05307"></a>05307                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05308"></a>05308                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05309"></a>05309                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05310"></a>05310                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05311"></a>05311                         <span class="comment">/* --- */</span>
<a name="l05312"></a>05312                         <span class="stringliteral">&quot;movq      %%mm7, %%mm3 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l05313"></a>05313                         <span class="stringliteral">&quot;psrlq       $32, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l05314"></a>05314                         <span class="stringliteral">&quot;paddsw    %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l05315"></a>05315                         <span class="stringliteral">&quot;movq      %%mm7, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM2 */</span>
<a name="l05316"></a>05316                         <span class="stringliteral">&quot;psrlq       $16, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 1 left word to the right */</span>
<a name="l05317"></a>05317                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l05318"></a>05318                         <span class="comment">/* --- */</span>
<a name="l05319"></a>05319                         <span class="stringliteral">&quot;movd      %%eax, %%mm1 \n\t&quot;</span>   <span class="comment">/* save EDX in MM1 */</span>
<a name="l05320"></a>05320                         <span class="stringliteral">&quot;movd      %%ebx, %%mm2 \n\t&quot;</span>   <span class="comment">/* save EDX in MM2 */</span>
<a name="l05321"></a>05321                         <span class="stringliteral">&quot;movd      %%edx, %%mm3 \n\t&quot;</span>   <span class="comment">/* save EDX in MM3 */</span>
<a name="l05322"></a>05322                         <span class="stringliteral">&quot;movd      %%mm7, %%eax \n\t&quot;</span>   <span class="comment">/* load summation result into EAX */</span>
<a name="l05323"></a>05323                         <span class="stringliteral">&quot;psraw       $15, %%mm7 \n\t&quot;</span>   <span class="comment">/* spread sign bit of the result */</span>
<a name="l05324"></a>05324                         <span class="stringliteral">&quot;movd      %%mm5, %%ebx \n\t&quot;</span>   <span class="comment">/* load Divisor into EBX */</span>
<a name="l05325"></a>05325                         <span class="stringliteral">&quot;movd      %%mm7, %%edx \n\t&quot;</span>   <span class="comment">/* fill EDX with a sign bit */</span>
<a name="l05326"></a>05326                         <span class="stringliteral">&quot;idivw             %%bx \n\t&quot;</span>   <span class="comment">/* IDIV - VERY EXPENSIVE */</span>
<a name="l05327"></a>05327                         <span class="stringliteral">&quot;movd      %%eax, %%mm7 \n\t&quot;</span>   <span class="comment">/* move result of division into MM7 */</span>
<a name="l05328"></a>05328                         <span class="stringliteral">&quot;packuswb  %%mm0, %%mm7 \n\t&quot;</span>   <span class="comment">/* pack division result with saturation */</span>
<a name="l05329"></a>05329                         <span class="stringliteral">&quot;movd      %%mm7, %%eax \n\t&quot;</span>   <span class="comment">/* copy saturated result into EAX */</span>
<a name="l05330"></a>05330                         <span class="stringliteral">&quot;mov      %%al, (%%edi) \n\t&quot;</span>   <span class="comment">/* copy a byte result into Dest */</span>
<a name="l05331"></a>05331                         <span class="stringliteral">&quot;movd      %%mm3, %%edx \n\t&quot;</span>   <span class="comment">/* restore saved EDX */</span>
<a name="l05332"></a>05332                         <span class="stringliteral">&quot;movd      %%mm2, %%ebx \n\t&quot;</span>   <span class="comment">/* restore saved EBX */</span>
<a name="l05333"></a>05333                         <span class="stringliteral">&quot;movd      %%mm1, %%eax \n\t&quot;</span>   <span class="comment">/* restore saved EAX */</span>
<a name="l05334"></a>05334                         <span class="comment">/* -- */</span>
<a name="l05335"></a>05335                         <span class="stringliteral">&quot;movd      %%mm6, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer to the top pixel */</span>
<a name="l05336"></a>05336                         <span class="stringliteral">&quot;sub        $208, %%edx \n\t&quot;</span>   <span class="comment">/* EDX = Kernel address */</span>
<a name="l05337"></a>05337                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l05338"></a>05338                         <span class="stringliteral">&quot;inc              %%edi \n\t&quot;</span>   <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l05339"></a>05339                         <span class="comment">/* --- */</span>
<a name="l05340"></a>05340                         <span class="stringliteral">&quot;dec              %%ecx \n\t&quot;</span>   <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l05341"></a>05341                         <span class="stringliteral">&quot;jnz            .L10352 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l05342"></a>05342                         <span class="stringliteral">&quot;add          $8, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row in Src */</span>
<a name="l05343"></a>05343                         <span class="stringliteral">&quot;add          $8, %%edi \n\t&quot;</span>   <span class="comment">/* move to the next row in Dest */</span>
<a name="l05344"></a>05344                         <span class="stringliteral">&quot;dec              %%ebx \n\t&quot;</span>   <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l05345"></a>05345                         <span class="stringliteral">&quot;jnz            .L10350 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l05346"></a>05346                         <span class="comment">/* --- */</span>
<a name="l05347"></a>05347                         <span class="stringliteral">&quot;emms                   \n\t&quot;</span>   <span class="comment">/* exit MMX state */</span>
<a name="l05348"></a>05348                         <span class="stringliteral">&quot;popa                   \n\t&quot;</span>:<span class="stringliteral">&quot;=m&quot;</span> (Dest)       <span class="comment">/* %0 */</span>
<a name="l05349"></a>05349                         :<span class="stringliteral">&quot;m&quot;</span>(Src),              <span class="comment">/* %1 */</span>
<a name="l05350"></a>05350                         <span class="stringliteral">&quot;m&quot;</span>(rows),              <span class="comment">/* %2 */</span>
<a name="l05351"></a>05351                         <span class="stringliteral">&quot;m&quot;</span>(columns),           <span class="comment">/* %3 */</span>
<a name="l05352"></a>05352                         <span class="stringliteral">&quot;m&quot;</span>(Kernel),            <span class="comment">/* %4 */</span>
<a name="l05353"></a>05353                         <span class="stringliteral">&quot;m&quot;</span>(Divisor)            <span class="comment">/* %5 */</span>
<a name="l05354"></a>05354                         );
<a name="l05355"></a>05355 <span class="preprocessor">#endif</span>
<a name="l05356"></a>05356 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l05357"></a>05357 <span class="preprocessor"></span>                <span class="keywordflow">return</span> (0);
<a name="l05358"></a>05358         } <span class="keywordflow">else</span> {
<a name="l05359"></a>05359                 <span class="comment">/* No non-MMX implementation yet */</span>
<a name="l05360"></a>05360                 <span class="keywordflow">return</span> (-1);
<a name="l05361"></a>05361         }
<a name="l05362"></a>05362 }
<a name="l05363"></a>05363 
<a name="l05378"></a><a class="code" href="_s_d_l2__image_filter_8c.html#ac329e5a3b60351768c96c94db9f9cf97">05378</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#ac329e5a3b60351768c96c94db9f9cf97" title="Filter using ConvolveKernel3x3ShiftRight: Dij = saturation0and255( ... )">SDL_imageFilterConvolveKernel3x3ShiftRight</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">int</span> rows, <span class="keywordtype">int</span> columns,
<a name="l05379"></a>05379                                                                                            <span class="keywordtype">signed</span> <span class="keywordtype">short</span> *Kernel, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> NRightShift)
<a name="l05380"></a>05380 {
<a name="l05381"></a>05381         <span class="comment">/* Validate input parameters */</span>
<a name="l05382"></a>05382         <span class="keywordflow">if</span> ((Src == NULL) || (Dest == NULL) || (Kernel == NULL))
<a name="l05383"></a>05383                 <span class="keywordflow">return</span>(-1);
<a name="l05384"></a>05384 
<a name="l05385"></a>05385         <span class="keywordflow">if</span> ((columns &lt; 3) || (rows &lt; 3) || (NRightShift &gt; 7))
<a name="l05386"></a>05386                 <span class="keywordflow">return</span> (-1);
<a name="l05387"></a>05387 
<a name="l05388"></a>05388         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>())) {
<a name="l05389"></a>05389 <span class="comment">//#ifdef USE_MMX</span>
<a name="l05390"></a>05390 <span class="preprocessor">#if defined(USE_MMX) &amp;&amp; defined(i386)</span>
<a name="l05391"></a>05391 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l05392"></a>05392 <span class="preprocessor"></span>                __asm
<a name="l05393"></a>05393                 {
<a name="l05394"></a>05394                         pusha
<a name="l05395"></a>05395                                 pxor mm0, mm0           <span class="comment">/* zero MM0 */</span>
<a name="l05396"></a>05396                                 xor ebx, ebx    <span class="comment">/* zero EBX */</span>
<a name="l05397"></a>05397                                 mov bl, NRightShift     <span class="comment">/* load NRightShift into BL */</span>
<a name="l05398"></a>05398                                 movd mm4, ebx           <span class="comment">/* copy NRightShift into MM4 */</span>
<a name="l05399"></a>05399                                 mov edx, Kernel         <span class="comment">/* load Kernel address into EDX */</span>
<a name="l05400"></a>05400                                 movq mm5, [edx]         <span class="comment">/* MM5 = {0,K2,K1,K0} */</span>
<a name="l05401"></a>05401                         add edx, 8      <span class="comment">/* second row              |K0 K1 K2 0| */</span>
<a name="l05402"></a>05402                                 movq mm6, [edx]         <span class="comment">/* MM6 = {0,K5,K4,K3}  K = |K3 K4 K5 0| */</span>
<a name="l05403"></a>05403                         add edx, 8      <span class="comment">/* third row               |K6 K7 K8 0| */</span>
<a name="l05404"></a>05404                                 movq mm7, [edx]         <span class="comment">/* MM7 = {0,K8,K7,K6} */</span>
<a name="l05405"></a>05405                         <span class="comment">/* ---, */</span>
<a name="l05406"></a>05406                         mov eax, columns        <span class="comment">/* load columns into EAX */</span>
<a name="l05407"></a>05407                                 mov esi, Src    <span class="comment">/* ESI = Src row 0 address */</span>
<a name="l05408"></a>05408                                 mov edi, Dest           <span class="comment">/* load Dest address to EDI */</span>
<a name="l05409"></a>05409                                 add edi, eax    <span class="comment">/* EDI = EDI + columns */</span>
<a name="l05410"></a>05410                                 inc              edi            <span class="comment">/* 1 byte offset from the left edge */</span>
<a name="l05411"></a>05411                                 mov edx, rows           <span class="comment">/* initialize ROWS counter */</span>
<a name="l05412"></a>05412                                 sub edx, 2      <span class="comment">/* do not use first and last row */</span>
<a name="l05413"></a>05413                                 <span class="comment">/* ---, */</span>
<a name="l05414"></a>05414 L10360:
<a name="l05415"></a>05415                         mov ecx, eax    <span class="comment">/* initialize COLUMS counter */</span>
<a name="l05416"></a>05416                                 sub ecx, 2      <span class="comment">/* do not use first and last column */</span>
<a name="l05417"></a>05417                                 align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l05418"></a>05418 L10362:
<a name="l05419"></a>05419                         <span class="comment">/* ---, */</span>
<a name="l05420"></a>05420                         movq mm1, [esi]         <span class="comment">/* load 8 bytes of the image first row */</span>
<a name="l05421"></a>05421                         add esi, eax    <span class="comment">/* move one row below */</span>
<a name="l05422"></a>05422                                 movq mm2, [esi]         <span class="comment">/* load 8 bytes of the image second row */</span>
<a name="l05423"></a>05423                         add esi, eax    <span class="comment">/* move one row below */</span>
<a name="l05424"></a>05424                                 movq mm3, [esi]         <span class="comment">/* load 8 bytes of the image third row */</span>
<a name="l05425"></a>05425                         punpcklbw mm1, mm0      <span class="comment">/* unpack first 4 bytes into words */</span>
<a name="l05426"></a>05426                                 punpcklbw mm2, mm0      <span class="comment">/* unpack first 4 bytes into words */</span>
<a name="l05427"></a>05427                                 punpcklbw mm3, mm0      <span class="comment">/* unpack first 4 bytes into words */</span>
<a name="l05428"></a>05428                                 psrlw mm1, mm4          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05429"></a>05429                                 psrlw mm2, mm4          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05430"></a>05430                                 psrlw mm3, mm4          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05431"></a>05431                                 pmullw mm1, mm5         <span class="comment">/* multiply words first row  image*Kernel */</span>
<a name="l05432"></a>05432                                 pmullw mm2, mm6         <span class="comment">/* multiply words second row image*Kernel */</span>
<a name="l05433"></a>05433                                 pmullw mm3, mm7         <span class="comment">/* multiply words third row  image*Kernel */</span>
<a name="l05434"></a>05434                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the first and second rows */</span>
<a name="l05435"></a>05435                                 paddsw mm1, mm3         <span class="comment">/* add 4 words of the third row and result */</span>
<a name="l05436"></a>05436                                 movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05437"></a>05437                                 psrlq mm1, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l05438"></a>05438                                 paddsw mm1, mm2         <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l05439"></a>05439                                 movq mm3, mm1           <span class="comment">/* copy MM1 into MM3 */</span>
<a name="l05440"></a>05440                                 psrlq mm1, 16           <span class="comment">/* shift 1 left word to the right */</span>
<a name="l05441"></a>05441                                 paddsw mm1, mm3         <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l05442"></a>05442                                 packuswb mm1, mm0       <span class="comment">/* pack shift result with saturation */</span>
<a name="l05443"></a>05443                                 movd ebx, mm1           <span class="comment">/* copy saturated result into EBX */</span>
<a name="l05444"></a>05444                                 mov [edi], bl           <span class="comment">/* copy a byte result into Dest */</span>
<a name="l05445"></a>05445                                 <span class="comment">/* --, */</span>
<a name="l05446"></a>05446                                 sub esi, eax    <span class="comment">/* move two rows up */</span>
<a name="l05447"></a>05447                                 sub esi, eax
<a name="l05448"></a>05448                                 inc              esi            <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l05449"></a>05449                                 inc              edi            <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l05450"></a>05450                                 <span class="comment">/* ---, */</span>
<a name="l05451"></a>05451                                 dec              ecx            <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l05452"></a>05452                                 jnz            L10362           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l05453"></a>05453                                 add esi, 2      <span class="comment">/* move to the next row in Src */</span>
<a name="l05454"></a>05454                                 add edi, 2      <span class="comment">/* move to the next row in Dest */</span>
<a name="l05455"></a>05455                                 dec              edx            <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l05456"></a>05456                                 jnz            L10360           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l05457"></a>05457                                 <span class="comment">/* ---, */</span>
<a name="l05458"></a>05458                                 emms                            <span class="comment">/* exit MMX state */</span>
<a name="l05459"></a>05459                                 popa
<a name="l05460"></a>05460                 }
<a name="l05461"></a>05461 <span class="preprocessor">#else</span>
<a name="l05462"></a>05462 <span class="preprocessor"></span>                <span class="keyword">asm</span> <span class="keyword">volatile</span>
<a name="l05463"></a>05463                         (<span class="stringliteral">&quot;pusha              \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm0, %%mm0 \n\t&quot;</span>        <span class="comment">/* zero MM0 */</span>
<a name="l05464"></a>05464                         <span class="stringliteral">&quot;xor       %%ebx, %%ebx \n\t&quot;</span>   <span class="comment">/* zero EBX */</span>
<a name="l05465"></a>05465                         <span class="stringliteral">&quot;mov           %5, %%bl \n\t&quot;</span>   <span class="comment">/* load NRightShift into BL */</span>
<a name="l05466"></a>05466                         <span class="stringliteral">&quot;movd      %%ebx, %%mm4 \n\t&quot;</span>   <span class="comment">/* copy NRightShift into MM4 */</span>
<a name="l05467"></a>05467                         <span class="stringliteral">&quot;mov          %4, %%edx \n\t&quot;</span>   <span class="comment">/* load Kernel address into EDX */</span>
<a name="l05468"></a>05468                         <span class="stringliteral">&quot;movq    (%%edx), %%mm5 \n\t&quot;</span>   <span class="comment">/* MM5 = {0,K2,K1,K0} */</span>
<a name="l05469"></a>05469                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* second row              |K0 K1 K2 0| */</span>
<a name="l05470"></a>05470                         <span class="stringliteral">&quot;movq    (%%edx), %%mm6 \n\t&quot;</span>   <span class="comment">/* MM6 = {0,K5,K4,K3}  K = |K3 K4 K5 0| */</span>
<a name="l05471"></a>05471                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* third row               |K6 K7 K8 0| */</span>
<a name="l05472"></a>05472                         <span class="stringliteral">&quot;movq    (%%edx), %%mm7 \n\t&quot;</span>   <span class="comment">/* MM7 = {0,K8,K7,K6} */</span>
<a name="l05473"></a>05473                         <span class="comment">/* --- */</span>
<a name="l05474"></a>05474                         <span class="stringliteral">&quot;mov          %3, %%eax \n\t&quot;</span>   <span class="comment">/* load columns into EAX */</span>
<a name="l05475"></a>05475                         <span class="stringliteral">&quot;mov          %1, %%esi \n\t&quot;</span>   <span class="comment">/* ESI = Src row 0 address */</span>
<a name="l05476"></a>05476                         <span class="stringliteral">&quot;mov          %0, %%edi \n\t&quot;</span>   <span class="comment">/* load Dest address to EDI */</span>
<a name="l05477"></a>05477                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span>   <span class="comment">/* EDI = EDI + columns */</span>
<a name="l05478"></a>05478                         <span class="stringliteral">&quot;inc              %%edi \n\t&quot;</span>   <span class="comment">/* 1 byte offset from the left edge */</span>
<a name="l05479"></a>05479                         <span class="stringliteral">&quot;mov          %2, %%edx \n\t&quot;</span>   <span class="comment">/* initialize ROWS counter */</span>
<a name="l05480"></a>05480                         <span class="stringliteral">&quot;sub          $2, %%edx \n\t&quot;</span>   <span class="comment">/* do not use first and last row */</span>
<a name="l05481"></a>05481                         <span class="comment">/* --- */</span>
<a name="l05482"></a>05482                         <span class="stringliteral">&quot;.L10360:               \n\t&quot;</span> <span class="stringliteral">&quot;mov       %%eax, %%ecx \n\t&quot;</span>     <span class="comment">/* initialize COLUMS counter */</span>
<a name="l05483"></a>05483                         <span class="stringliteral">&quot;sub          $2, %%ecx \n\t&quot;</span>   <span class="comment">/* do not use first and last column */</span>
<a name="l05484"></a>05484                         <span class="stringliteral">&quot;.align 16              \n\t&quot;</span>   <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l05485"></a>05485                         <span class="stringliteral">&quot;.L10362:               \n\t&quot;</span>
<a name="l05486"></a>05486                         <span class="comment">/* --- */</span>
<a name="l05487"></a>05487                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the image first row */</span>
<a name="l05488"></a>05488                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move one row below */</span>
<a name="l05489"></a>05489                         <span class="stringliteral">&quot;movq    (%%esi), %%mm2 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the image second row */</span>
<a name="l05490"></a>05490                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move one row below */</span>
<a name="l05491"></a>05491                         <span class="stringliteral">&quot;movq    (%%esi), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the image third row */</span>
<a name="l05492"></a>05492                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first 4 bytes into words */</span>
<a name="l05493"></a>05493                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack first 4 bytes into words */</span>
<a name="l05494"></a>05494                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm3 \n\t&quot;</span>   <span class="comment">/* unpack first 4 bytes into words */</span>
<a name="l05495"></a>05495                         <span class="stringliteral">&quot;psrlw     %%mm4, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05496"></a>05496                         <span class="stringliteral">&quot;psrlw     %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05497"></a>05497                         <span class="stringliteral">&quot;psrlw     %%mm4, %%mm3 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05498"></a>05498                         <span class="stringliteral">&quot;pmullw    %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* multiply words first row  image*Kernel */</span>
<a name="l05499"></a>05499                         <span class="stringliteral">&quot;pmullw    %%mm6, %%mm2 \n\t&quot;</span>   <span class="comment">/* multiply words second row image*Kernel */</span>
<a name="l05500"></a>05500                         <span class="stringliteral">&quot;pmullw    %%mm7, %%mm3 \n\t&quot;</span>   <span class="comment">/* multiply words third row  image*Kernel */</span>
<a name="l05501"></a>05501                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the first and second rows */</span>
<a name="l05502"></a>05502                         <span class="stringliteral">&quot;paddsw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the third row and result */</span>
<a name="l05503"></a>05503                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05504"></a>05504                         <span class="stringliteral">&quot;psrlq       $32, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l05505"></a>05505                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l05506"></a>05506                         <span class="stringliteral">&quot;movq      %%mm1, %%mm3 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM3 */</span>
<a name="l05507"></a>05507                         <span class="stringliteral">&quot;psrlq       $16, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift 1 left word to the right */</span>
<a name="l05508"></a>05508                         <span class="stringliteral">&quot;paddsw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l05509"></a>05509                         <span class="stringliteral">&quot;packuswb  %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* pack shift result with saturation */</span>
<a name="l05510"></a>05510                         <span class="stringliteral">&quot;movd      %%mm1, %%ebx \n\t&quot;</span>   <span class="comment">/* copy saturated result into EBX */</span>
<a name="l05511"></a>05511                         <span class="stringliteral">&quot;mov      %%bl, (%%edi) \n\t&quot;</span>   <span class="comment">/* copy a byte result into Dest */</span>
<a name="l05512"></a>05512                         <span class="comment">/* -- */</span>
<a name="l05513"></a>05513                         <span class="stringliteral">&quot;sub       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move two rows up */</span>
<a name="l05514"></a>05514                         <span class="stringliteral">&quot;sub       %%eax, %%esi \n\t&quot;</span> <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>     <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l05515"></a>05515                         <span class="stringliteral">&quot;inc              %%edi \n\t&quot;</span>   <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l05516"></a>05516                         <span class="comment">/* --- */</span>
<a name="l05517"></a>05517                         <span class="stringliteral">&quot;dec              %%ecx \n\t&quot;</span>   <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l05518"></a>05518                         <span class="stringliteral">&quot;jnz            .L10362 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l05519"></a>05519                         <span class="stringliteral">&quot;add          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row in Src */</span>
<a name="l05520"></a>05520                         <span class="stringliteral">&quot;add          $2, %%edi \n\t&quot;</span>   <span class="comment">/* move to the next row in Dest */</span>
<a name="l05521"></a>05521                         <span class="stringliteral">&quot;dec              %%edx \n\t&quot;</span>   <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l05522"></a>05522                         <span class="stringliteral">&quot;jnz            .L10360 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l05523"></a>05523                         <span class="comment">/* --- */</span>
<a name="l05524"></a>05524                         <span class="stringliteral">&quot;emms                   \n\t&quot;</span>   <span class="comment">/* exit MMX state */</span>
<a name="l05525"></a>05525                         <span class="stringliteral">&quot;popa                   \n\t&quot;</span>:<span class="stringliteral">&quot;=m&quot;</span> (Dest)       <span class="comment">/* %0 */</span>
<a name="l05526"></a>05526                         :<span class="stringliteral">&quot;m&quot;</span>(Src),              <span class="comment">/* %1 */</span>
<a name="l05527"></a>05527                         <span class="stringliteral">&quot;m&quot;</span>(rows),              <span class="comment">/* %2 */</span>
<a name="l05528"></a>05528                         <span class="stringliteral">&quot;m&quot;</span>(columns),           <span class="comment">/* %3 */</span>
<a name="l05529"></a>05529                         <span class="stringliteral">&quot;m&quot;</span>(Kernel),            <span class="comment">/* %4 */</span>
<a name="l05530"></a>05530                         <span class="stringliteral">&quot;m&quot;</span>(NRightShift)        <span class="comment">/* %5 */</span>
<a name="l05531"></a>05531                         );
<a name="l05532"></a>05532 <span class="preprocessor">#endif</span>
<a name="l05533"></a>05533 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l05534"></a>05534 <span class="preprocessor"></span>                <span class="keywordflow">return</span> (0);
<a name="l05535"></a>05535         } <span class="keywordflow">else</span> {
<a name="l05536"></a>05536                 <span class="comment">/* No non-MMX implementation yet */</span>
<a name="l05537"></a>05537                 <span class="keywordflow">return</span> (-1);
<a name="l05538"></a>05538         }
<a name="l05539"></a>05539 }
<a name="l05540"></a>05540 
<a name="l05555"></a><a class="code" href="_s_d_l2__image_filter_8c.html#a5253738dc4c892352b078d9a7dec2b20">05555</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a5253738dc4c892352b078d9a7dec2b20" title="Filter using ConvolveKernel5x5ShiftRight: Dij = saturation0and255( ... )">SDL_imageFilterConvolveKernel5x5ShiftRight</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">int</span> rows, <span class="keywordtype">int</span> columns,
<a name="l05556"></a>05556                                                                                            <span class="keywordtype">signed</span> <span class="keywordtype">short</span> *Kernel, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> NRightShift)
<a name="l05557"></a>05557 {
<a name="l05558"></a>05558         <span class="comment">/* Validate input parameters */</span>
<a name="l05559"></a>05559         <span class="keywordflow">if</span> ((Src == NULL) || (Dest == NULL) || (Kernel == NULL))
<a name="l05560"></a>05560                 <span class="keywordflow">return</span>(-1);
<a name="l05561"></a>05561 
<a name="l05562"></a>05562         <span class="keywordflow">if</span> ((columns &lt; 5) || (rows &lt; 5) || (NRightShift &gt; 7))
<a name="l05563"></a>05563                 <span class="keywordflow">return</span> (-1);
<a name="l05564"></a>05564 
<a name="l05565"></a>05565         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>())) {
<a name="l05566"></a>05566 <span class="comment">//#ifdef USE_MMX</span>
<a name="l05567"></a>05567 <span class="preprocessor">#if defined(USE_MMX) &amp;&amp; defined(i386)</span>
<a name="l05568"></a>05568 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l05569"></a>05569 <span class="preprocessor"></span>                __asm
<a name="l05570"></a>05570                 {
<a name="l05571"></a>05571                         pusha
<a name="l05572"></a>05572                                 pxor mm0, mm0           <span class="comment">/* zero MM0 */</span>
<a name="l05573"></a>05573                                 xor ebx, ebx    <span class="comment">/* zero EBX */</span>
<a name="l05574"></a>05574                                 mov bl, NRightShift     <span class="comment">/* load NRightShift into BL */</span>
<a name="l05575"></a>05575                                 movd mm5, ebx           <span class="comment">/* copy NRightShift into MM5 */</span>
<a name="l05576"></a>05576                                 mov edx, Kernel         <span class="comment">/* load Kernel address into EDX */</span>
<a name="l05577"></a>05577                                 mov esi, Src    <span class="comment">/* load Src  address to ESI */</span>
<a name="l05578"></a>05578                                 mov edi, Dest           <span class="comment">/* load Dest address to EDI */</span>
<a name="l05579"></a>05579                                 add edi, 2      <span class="comment">/* 2 column offset from the left edge */</span>
<a name="l05580"></a>05580                                 mov eax, columns        <span class="comment">/* load columns into EAX */</span>
<a name="l05581"></a>05581                                 shl eax, 1      <span class="comment">/* EAX = columns * 2 */</span>
<a name="l05582"></a>05582                                 add edi, eax    <span class="comment">/* 2 row offset from the top edge */</span>
<a name="l05583"></a>05583                                 shr eax, 1      <span class="comment">/* EAX = columns */</span>
<a name="l05584"></a>05584                                 mov ebx, rows           <span class="comment">/* initialize ROWS counter */</span>
<a name="l05585"></a>05585                                 sub ebx, 4      <span class="comment">/* do not use first 2 and last 2 rows */</span>
<a name="l05586"></a>05586                                 <span class="comment">/* ---, */</span>
<a name="l05587"></a>05587 L10370:
<a name="l05588"></a>05588                         mov ecx, eax    <span class="comment">/* initialize COLUMNS counter */</span>
<a name="l05589"></a>05589                                 sub ecx, 4      <span class="comment">/* do not use first 2 and last 2 columns */</span>
<a name="l05590"></a>05590                                 align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l05591"></a>05591 L10372:
<a name="l05592"></a>05592                         pxor mm7, mm7           <span class="comment">/* zero MM7 (accumulator) */</span>
<a name="l05593"></a>05593                                 movd mm6, esi           <span class="comment">/* save ESI in MM6 */</span>
<a name="l05594"></a>05594                                 <span class="comment">/* --- 1 */</span>
<a name="l05595"></a>05595                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05596"></a>05596                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05597"></a>05597                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05598"></a>05598                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05599"></a>05599                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05600"></a>05600                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05601"></a>05601                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05602"></a>05602                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05603"></a>05603                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05604"></a>05604                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05605"></a>05605                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05606"></a>05606                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l05607"></a>05607                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l05608"></a>05608                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05609"></a>05609                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05610"></a>05610                                 <span class="comment">/* --- 2 */</span>
<a name="l05611"></a>05611                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05612"></a>05612                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05613"></a>05613                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05614"></a>05614                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05615"></a>05615                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05616"></a>05616                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05617"></a>05617                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05618"></a>05618                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05619"></a>05619                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05620"></a>05620                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05621"></a>05621                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05622"></a>05622                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l05623"></a>05623                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l05624"></a>05624                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05625"></a>05625                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05626"></a>05626                                 <span class="comment">/* --- 3 */</span>
<a name="l05627"></a>05627                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05628"></a>05628                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05629"></a>05629                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05630"></a>05630                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05631"></a>05631                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05632"></a>05632                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05633"></a>05633                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05634"></a>05634                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05635"></a>05635                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05636"></a>05636                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05637"></a>05637                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05638"></a>05638                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l05639"></a>05639                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l05640"></a>05640                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05641"></a>05641                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05642"></a>05642                                 <span class="comment">/* --- 4 */</span>
<a name="l05643"></a>05643                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05644"></a>05644                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05645"></a>05645                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05646"></a>05646                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05647"></a>05647                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05648"></a>05648                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05649"></a>05649                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05650"></a>05650                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05651"></a>05651                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05652"></a>05652                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05653"></a>05653                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05654"></a>05654                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l05655"></a>05655                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l05656"></a>05656                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05657"></a>05657                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05658"></a>05658                                 <span class="comment">/* --- 5 */</span>
<a name="l05659"></a>05659                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05660"></a>05660                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05661"></a>05661                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05662"></a>05662                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05663"></a>05663                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05664"></a>05664                         punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05665"></a>05665                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05666"></a>05666                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05667"></a>05667                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05668"></a>05668                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l05669"></a>05669                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l05670"></a>05670                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05671"></a>05671                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05672"></a>05672                                 <span class="comment">/* ---, */</span>
<a name="l05673"></a>05673                                 movq mm3, mm7           <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l05674"></a>05674                                 psrlq mm7, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l05675"></a>05675                                 paddsw mm7, mm3         <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l05676"></a>05676                                 movq mm2, mm7           <span class="comment">/* copy MM7 into MM2 */</span>
<a name="l05677"></a>05677                                 psrlq mm7, 16           <span class="comment">/* shift 1 left word to the right */</span>
<a name="l05678"></a>05678                                 paddsw mm7, mm2         <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l05679"></a>05679                                 movd mm1, eax           <span class="comment">/* save EAX in MM1 */</span>
<a name="l05680"></a>05680                                 packuswb mm7, mm0       <span class="comment">/* pack division result with saturation */</span>
<a name="l05681"></a>05681                                 movd eax, mm7           <span class="comment">/* copy saturated result into EAX */</span>
<a name="l05682"></a>05682                                 mov [edi], al           <span class="comment">/* copy a byte result into Dest */</span>
<a name="l05683"></a>05683                                 movd eax, mm1           <span class="comment">/* restore saved EAX */</span>
<a name="l05684"></a>05684                                 <span class="comment">/* --, */</span>
<a name="l05685"></a>05685                                 movd esi, mm6           <span class="comment">/* move Src pointer to the top pixel */</span>
<a name="l05686"></a>05686                                 sub edx, 72     <span class="comment">/* EDX = Kernel address */</span>
<a name="l05687"></a>05687                                 inc              esi            <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l05688"></a>05688                                 inc              edi            <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l05689"></a>05689                                 <span class="comment">/* ---, */</span>
<a name="l05690"></a>05690                                 dec              ecx            <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l05691"></a>05691                                 jnz            L10372           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l05692"></a>05692                                 add esi, 4      <span class="comment">/* move to the next row in Src */</span>
<a name="l05693"></a>05693                                 add edi, 4      <span class="comment">/* move to the next row in Dest */</span>
<a name="l05694"></a>05694                                 dec              ebx            <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l05695"></a>05695                                 jnz            L10370           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l05696"></a>05696                                 <span class="comment">/* ---, */</span>
<a name="l05697"></a>05697                                 emms                            <span class="comment">/* exit MMX state */</span>
<a name="l05698"></a>05698                                 popa
<a name="l05699"></a>05699                 }
<a name="l05700"></a>05700 <span class="preprocessor">#else</span>
<a name="l05701"></a>05701 <span class="preprocessor"></span>                <span class="keyword">asm</span> <span class="keyword">volatile</span>
<a name="l05702"></a>05702                         (<span class="stringliteral">&quot;pusha              \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm0, %%mm0 \n\t&quot;</span>        <span class="comment">/* zero MM0 */</span>
<a name="l05703"></a>05703                         <span class="stringliteral">&quot;xor       %%ebx, %%ebx \n\t&quot;</span>   <span class="comment">/* zero EBX */</span>
<a name="l05704"></a>05704                         <span class="stringliteral">&quot;mov           %5, %%bl \n\t&quot;</span>   <span class="comment">/* load NRightShift into BL */</span>
<a name="l05705"></a>05705                         <span class="stringliteral">&quot;movd      %%ebx, %%mm5 \n\t&quot;</span>   <span class="comment">/* copy NRightShift into MM5 */</span>
<a name="l05706"></a>05706                         <span class="stringliteral">&quot;mov          %4, %%edx \n\t&quot;</span>   <span class="comment">/* load Kernel address into EDX */</span>
<a name="l05707"></a>05707                         <span class="stringliteral">&quot;mov          %1, %%esi \n\t&quot;</span>   <span class="comment">/* load Src  address to ESI */</span>
<a name="l05708"></a>05708                         <span class="stringliteral">&quot;mov          %0, %%edi \n\t&quot;</span>   <span class="comment">/* load Dest address to EDI */</span>
<a name="l05709"></a>05709                         <span class="stringliteral">&quot;add          $2, %%edi \n\t&quot;</span>   <span class="comment">/* 2 column offset from the left edge */</span>
<a name="l05710"></a>05710                         <span class="stringliteral">&quot;mov          %3, %%eax \n\t&quot;</span>   <span class="comment">/* load columns into EAX */</span>
<a name="l05711"></a>05711                         <span class="stringliteral">&quot;shl          $1, %%eax \n\t&quot;</span>   <span class="comment">/* EAX = columns * 2 */</span>
<a name="l05712"></a>05712                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span>   <span class="comment">/* 2 row offset from the top edge */</span>
<a name="l05713"></a>05713                         <span class="stringliteral">&quot;shr          $1, %%eax \n\t&quot;</span>   <span class="comment">/* EAX = columns */</span>
<a name="l05714"></a>05714                         <span class="stringliteral">&quot;mov          %2, %%ebx \n\t&quot;</span>   <span class="comment">/* initialize ROWS counter */</span>
<a name="l05715"></a>05715                         <span class="stringliteral">&quot;sub          $4, %%ebx \n\t&quot;</span>   <span class="comment">/* do not use first 2 and last 2 rows */</span>
<a name="l05716"></a>05716                         <span class="comment">/* --- */</span>
<a name="l05717"></a>05717                         <span class="stringliteral">&quot;.L10370:               \n\t&quot;</span> <span class="stringliteral">&quot;mov       %%eax, %%ecx \n\t&quot;</span>     <span class="comment">/* initialize COLUMNS counter */</span>
<a name="l05718"></a>05718                         <span class="stringliteral">&quot;sub          $4, %%ecx \n\t&quot;</span>   <span class="comment">/* do not use first 2 and last 2 columns */</span>
<a name="l05719"></a>05719                         <span class="stringliteral">&quot;.align 16              \n\t&quot;</span>   <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l05720"></a>05720                         <span class="stringliteral">&quot;.L10372:               \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm7, %%mm7 \n\t&quot;</span>     <span class="comment">/* zero MM7 (accumulator) */</span>
<a name="l05721"></a>05721                         <span class="stringliteral">&quot;movd      %%esi, %%mm6 \n\t&quot;</span>   <span class="comment">/* save ESI in MM6 */</span>
<a name="l05722"></a>05722                         <span class="comment">/* --- 1 */</span>
<a name="l05723"></a>05723                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05724"></a>05724                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05725"></a>05725                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05726"></a>05726                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05727"></a>05727                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05728"></a>05728                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05729"></a>05729                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05730"></a>05730                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05731"></a>05731                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05732"></a>05732                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05733"></a>05733                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05734"></a>05734                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05735"></a>05735                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05736"></a>05736                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05737"></a>05737                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05738"></a>05738                         <span class="comment">/* --- 2 */</span>
<a name="l05739"></a>05739                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05740"></a>05740                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05741"></a>05741                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05742"></a>05742                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05743"></a>05743                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05744"></a>05744                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05745"></a>05745                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05746"></a>05746                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05747"></a>05747                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05748"></a>05748                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05749"></a>05749                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05750"></a>05750                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05751"></a>05751                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05752"></a>05752                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05753"></a>05753                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05754"></a>05754                         <span class="comment">/* --- 3 */</span>
<a name="l05755"></a>05755                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05756"></a>05756                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05757"></a>05757                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05758"></a>05758                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05759"></a>05759                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05760"></a>05760                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05761"></a>05761                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05762"></a>05762                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05763"></a>05763                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05764"></a>05764                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05765"></a>05765                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05766"></a>05766                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05767"></a>05767                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05768"></a>05768                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05769"></a>05769                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05770"></a>05770                         <span class="comment">/* --- 4 */</span>
<a name="l05771"></a>05771                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05772"></a>05772                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05773"></a>05773                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05774"></a>05774                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05775"></a>05775                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05776"></a>05776                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05777"></a>05777                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05778"></a>05778                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05779"></a>05779                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05780"></a>05780                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05781"></a>05781                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05782"></a>05782                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05783"></a>05783                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05784"></a>05784                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05785"></a>05785                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05786"></a>05786                         <span class="comment">/* --- 5 */</span>
<a name="l05787"></a>05787                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05788"></a>05788                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05789"></a>05789                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05790"></a>05790                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05791"></a>05791                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05792"></a>05792                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05793"></a>05793                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05794"></a>05794                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05795"></a>05795                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05796"></a>05796                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l05797"></a>05797                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l05798"></a>05798                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05799"></a>05799                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05800"></a>05800                         <span class="comment">/* --- */</span>
<a name="l05801"></a>05801                         <span class="stringliteral">&quot;movq      %%mm7, %%mm3 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l05802"></a>05802                         <span class="stringliteral">&quot;psrlq       $32, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l05803"></a>05803                         <span class="stringliteral">&quot;paddsw    %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l05804"></a>05804                         <span class="stringliteral">&quot;movq      %%mm7, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM2 */</span>
<a name="l05805"></a>05805                         <span class="stringliteral">&quot;psrlq       $16, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 1 left word to the right */</span>
<a name="l05806"></a>05806                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l05807"></a>05807                         <span class="stringliteral">&quot;movd      %%eax, %%mm1 \n\t&quot;</span>   <span class="comment">/* save EAX in MM1 */</span>
<a name="l05808"></a>05808                         <span class="stringliteral">&quot;packuswb  %%mm0, %%mm7 \n\t&quot;</span>   <span class="comment">/* pack division result with saturation */</span>
<a name="l05809"></a>05809                         <span class="stringliteral">&quot;movd      %%mm7, %%eax \n\t&quot;</span>   <span class="comment">/* copy saturated result into EAX */</span>
<a name="l05810"></a>05810                         <span class="stringliteral">&quot;mov      %%al, (%%edi) \n\t&quot;</span>   <span class="comment">/* copy a byte result into Dest */</span>
<a name="l05811"></a>05811                         <span class="stringliteral">&quot;movd      %%mm1, %%eax \n\t&quot;</span>   <span class="comment">/* restore saved EAX */</span>
<a name="l05812"></a>05812                         <span class="comment">/* -- */</span>
<a name="l05813"></a>05813                         <span class="stringliteral">&quot;movd      %%mm6, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer to the top pixel */</span>
<a name="l05814"></a>05814                         <span class="stringliteral">&quot;sub         $72, %%edx \n\t&quot;</span>   <span class="comment">/* EDX = Kernel address */</span>
<a name="l05815"></a>05815                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l05816"></a>05816                         <span class="stringliteral">&quot;inc              %%edi \n\t&quot;</span>   <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l05817"></a>05817                         <span class="comment">/* --- */</span>
<a name="l05818"></a>05818                         <span class="stringliteral">&quot;dec              %%ecx \n\t&quot;</span>   <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l05819"></a>05819                         <span class="stringliteral">&quot;jnz            .L10372 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l05820"></a>05820                         <span class="stringliteral">&quot;add          $4, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row in Src */</span>
<a name="l05821"></a>05821                         <span class="stringliteral">&quot;add          $4, %%edi \n\t&quot;</span>   <span class="comment">/* move to the next row in Dest */</span>
<a name="l05822"></a>05822                         <span class="stringliteral">&quot;dec              %%ebx \n\t&quot;</span>   <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l05823"></a>05823                         <span class="stringliteral">&quot;jnz            .L10370 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l05824"></a>05824                         <span class="comment">/* --- */</span>
<a name="l05825"></a>05825                         <span class="stringliteral">&quot;emms                   \n\t&quot;</span>   <span class="comment">/* exit MMX state */</span>
<a name="l05826"></a>05826                         <span class="stringliteral">&quot;popa                   \n\t&quot;</span>:<span class="stringliteral">&quot;=m&quot;</span> (Dest)       <span class="comment">/* %0 */</span>
<a name="l05827"></a>05827                         :<span class="stringliteral">&quot;m&quot;</span>(Src),              <span class="comment">/* %1 */</span>
<a name="l05828"></a>05828                         <span class="stringliteral">&quot;m&quot;</span>(rows),              <span class="comment">/* %2 */</span>
<a name="l05829"></a>05829                         <span class="stringliteral">&quot;m&quot;</span>(columns),           <span class="comment">/* %3 */</span>
<a name="l05830"></a>05830                         <span class="stringliteral">&quot;m&quot;</span>(Kernel),            <span class="comment">/* %4 */</span>
<a name="l05831"></a>05831                         <span class="stringliteral">&quot;m&quot;</span>(NRightShift)        <span class="comment">/* %5 */</span>
<a name="l05832"></a>05832                         );
<a name="l05833"></a>05833 <span class="preprocessor">#endif</span>
<a name="l05834"></a>05834 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l05835"></a>05835 <span class="preprocessor"></span>                <span class="keywordflow">return</span> (0);
<a name="l05836"></a>05836         } <span class="keywordflow">else</span> {
<a name="l05837"></a>05837                 <span class="comment">/* No non-MMX implementation yet */</span>
<a name="l05838"></a>05838                 <span class="keywordflow">return</span> (-1);
<a name="l05839"></a>05839         }
<a name="l05840"></a>05840 }
<a name="l05841"></a>05841 
<a name="l05856"></a><a class="code" href="_s_d_l2__image_filter_8c.html#a48b40065652dda699875f1425b9227a6">05856</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a48b40065652dda699875f1425b9227a6" title="Filter using ConvolveKernel7x7ShiftRight: Dij = saturation0and255( ... )">SDL_imageFilterConvolveKernel7x7ShiftRight</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">int</span> rows, <span class="keywordtype">int</span> columns,
<a name="l05857"></a>05857                                                                                            <span class="keywordtype">signed</span> <span class="keywordtype">short</span> *Kernel, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> NRightShift)
<a name="l05858"></a>05858 {
<a name="l05859"></a>05859         <span class="comment">/* Validate input parameters */</span>
<a name="l05860"></a>05860         <span class="keywordflow">if</span> ((Src == NULL) || (Dest == NULL) || (Kernel == NULL))
<a name="l05861"></a>05861                 <span class="keywordflow">return</span>(-1);
<a name="l05862"></a>05862 
<a name="l05863"></a>05863         <span class="keywordflow">if</span> ((columns &lt; 7) || (rows &lt; 7) || (NRightShift &gt; 7))
<a name="l05864"></a>05864                 <span class="keywordflow">return</span> (-1);
<a name="l05865"></a>05865 
<a name="l05866"></a>05866         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>())) {
<a name="l05867"></a>05867 <span class="comment">//#ifdef USE_MMX</span>
<a name="l05868"></a>05868 <span class="preprocessor">#if defined(USE_MMX) &amp;&amp; defined(i386)</span>
<a name="l05869"></a>05869 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l05870"></a>05870 <span class="preprocessor"></span>                __asm
<a name="l05871"></a>05871                 {
<a name="l05872"></a>05872                         pusha
<a name="l05873"></a>05873                                 pxor mm0, mm0           <span class="comment">/* zero MM0 */</span>
<a name="l05874"></a>05874                                 xor ebx, ebx    <span class="comment">/* zero EBX */</span>
<a name="l05875"></a>05875                                 mov bl, NRightShift     <span class="comment">/* load NRightShift into BL */</span>
<a name="l05876"></a>05876                                 movd mm5, ebx           <span class="comment">/* copy NRightShift into MM5 */</span>
<a name="l05877"></a>05877                                 mov edx, Kernel         <span class="comment">/* load Kernel address into EDX */</span>
<a name="l05878"></a>05878                                 mov esi, Src    <span class="comment">/* load Src  address to ESI */</span>
<a name="l05879"></a>05879                                 mov edi, Dest           <span class="comment">/* load Dest address to EDI */</span>
<a name="l05880"></a>05880                                 add edi, 3      <span class="comment">/* 3 column offset from the left edge */</span>
<a name="l05881"></a>05881                                 mov eax, columns        <span class="comment">/* load columns into EAX */</span>
<a name="l05882"></a>05882                                 add edi, eax    <span class="comment">/* 3 row offset from the top edge */</span>
<a name="l05883"></a>05883                                 add edi, eax
<a name="l05884"></a>05884                                 add edi, eax
<a name="l05885"></a>05885                                 mov ebx, rows           <span class="comment">/* initialize ROWS counter */</span>
<a name="l05886"></a>05886                                 sub ebx, 6      <span class="comment">/* do not use first 3 and last 3 rows */</span>
<a name="l05887"></a>05887                                 <span class="comment">/* ---, */</span>
<a name="l05888"></a>05888 L10380:
<a name="l05889"></a>05889                         mov ecx, eax    <span class="comment">/* initialize COLUMNS counter */</span>
<a name="l05890"></a>05890                                 sub ecx, 6      <span class="comment">/* do not use first 3 and last 3 columns */</span>
<a name="l05891"></a>05891                                 align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l05892"></a>05892 L10382:
<a name="l05893"></a>05893                         pxor mm7, mm7           <span class="comment">/* zero MM7 (accumulator) */</span>
<a name="l05894"></a>05894                                 movd mm6, esi           <span class="comment">/* save ESI in MM6 */</span>
<a name="l05895"></a>05895                                 <span class="comment">/* --- 1 */</span>
<a name="l05896"></a>05896                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05897"></a>05897                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05898"></a>05898                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05899"></a>05899                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05900"></a>05900                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05901"></a>05901                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05902"></a>05902                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05903"></a>05903                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05904"></a>05904                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05905"></a>05905                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05906"></a>05906                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05907"></a>05907                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l05908"></a>05908                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l05909"></a>05909                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05910"></a>05910                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05911"></a>05911                                 <span class="comment">/* --- 2 */</span>
<a name="l05912"></a>05912                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05913"></a>05913                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05914"></a>05914                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05915"></a>05915                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05916"></a>05916                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05917"></a>05917                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05918"></a>05918                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05919"></a>05919                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05920"></a>05920                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05921"></a>05921                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05922"></a>05922                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05923"></a>05923                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l05924"></a>05924                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l05925"></a>05925                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05926"></a>05926                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05927"></a>05927                                 <span class="comment">/* --- 3 */</span>
<a name="l05928"></a>05928                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05929"></a>05929                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05930"></a>05930                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05931"></a>05931                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05932"></a>05932                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05933"></a>05933                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05934"></a>05934                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05935"></a>05935                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05936"></a>05936                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05937"></a>05937                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05938"></a>05938                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05939"></a>05939                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l05940"></a>05940                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l05941"></a>05941                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05942"></a>05942                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05943"></a>05943                                 <span class="comment">/* --- 4 */</span>
<a name="l05944"></a>05944                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05945"></a>05945                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05946"></a>05946                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05947"></a>05947                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05948"></a>05948                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05949"></a>05949                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05950"></a>05950                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05951"></a>05951                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05952"></a>05952                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05953"></a>05953                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05954"></a>05954                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05955"></a>05955                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l05956"></a>05956                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l05957"></a>05957                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05958"></a>05958                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05959"></a>05959                                 <span class="comment">/* --- 5 */</span>
<a name="l05960"></a>05960                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05961"></a>05961                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05962"></a>05962                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05963"></a>05963                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05964"></a>05964                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05965"></a>05965                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05966"></a>05966                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05967"></a>05967                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05968"></a>05968                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05969"></a>05969                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05970"></a>05970                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05971"></a>05971                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l05972"></a>05972                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l05973"></a>05973                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05974"></a>05974                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05975"></a>05975                                 <span class="comment">/* --- 6 */</span>
<a name="l05976"></a>05976                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05977"></a>05977                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05978"></a>05978                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l05979"></a>05979                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05980"></a>05980                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05981"></a>05981                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05982"></a>05982                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05983"></a>05983                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05984"></a>05984                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05985"></a>05985                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05986"></a>05986                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l05987"></a>05987                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l05988"></a>05988                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l05989"></a>05989                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l05990"></a>05990                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l05991"></a>05991                                 <span class="comment">/* --- 7 */</span>
<a name="l05992"></a>05992                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l05993"></a>05993                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l05994"></a>05994                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05995"></a>05995                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l05996"></a>05996                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l05997"></a>05997                         punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l05998"></a>05998                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l05999"></a>05999                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06000"></a>06000                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06001"></a>06001                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06002"></a>06002                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l06003"></a>06003                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06004"></a>06004                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06005"></a>06005                                 <span class="comment">/* ---, */</span>
<a name="l06006"></a>06006                                 movq mm3, mm7           <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l06007"></a>06007                                 psrlq mm7, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l06008"></a>06008                                 paddsw mm7, mm3         <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l06009"></a>06009                                 movq mm2, mm7           <span class="comment">/* copy MM7 into MM2 */</span>
<a name="l06010"></a>06010                                 psrlq mm7, 16           <span class="comment">/* shift 1 left word to the right */</span>
<a name="l06011"></a>06011                                 paddsw mm7, mm2         <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l06012"></a>06012                                 movd mm1, eax           <span class="comment">/* save EAX in MM1 */</span>
<a name="l06013"></a>06013                                 packuswb mm7, mm0       <span class="comment">/* pack division result with saturation */</span>
<a name="l06014"></a>06014                                 movd eax, mm7           <span class="comment">/* copy saturated result into EAX */</span>
<a name="l06015"></a>06015                                 mov [edi], al           <span class="comment">/* copy a byte result into Dest */</span>
<a name="l06016"></a>06016                                 movd eax, mm1           <span class="comment">/* restore saved EAX */</span>
<a name="l06017"></a>06017                                 <span class="comment">/* --, */</span>
<a name="l06018"></a>06018                                 movd esi, mm6           <span class="comment">/* move Src pointer to the top pixel */</span>
<a name="l06019"></a>06019                                 sub edx, 104    <span class="comment">/* EDX = Kernel address */</span>
<a name="l06020"></a>06020                                 inc              esi            <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l06021"></a>06021                                 inc              edi            <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l06022"></a>06022                                 <span class="comment">/* ---, */</span>
<a name="l06023"></a>06023                                 dec              ecx            <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l06024"></a>06024                                 jnz            L10382           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l06025"></a>06025                                 add esi, 6      <span class="comment">/* move to the next row in Src */</span>
<a name="l06026"></a>06026                                 add edi, 6      <span class="comment">/* move to the next row in Dest */</span>
<a name="l06027"></a>06027                                 dec              ebx            <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l06028"></a>06028                                 jnz            L10380           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l06029"></a>06029                                 <span class="comment">/* ---, */</span>
<a name="l06030"></a>06030                                 emms                            <span class="comment">/* exit MMX state */</span>
<a name="l06031"></a>06031                                 popa
<a name="l06032"></a>06032                 }
<a name="l06033"></a>06033 <span class="preprocessor">#else</span>
<a name="l06034"></a>06034 <span class="preprocessor"></span>                <span class="keyword">asm</span> <span class="keyword">volatile</span>
<a name="l06035"></a>06035                         (<span class="stringliteral">&quot;pusha              \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm0, %%mm0 \n\t&quot;</span>        <span class="comment">/* zero MM0 */</span>
<a name="l06036"></a>06036                         <span class="stringliteral">&quot;xor       %%ebx, %%ebx \n\t&quot;</span>   <span class="comment">/* zero EBX */</span>
<a name="l06037"></a>06037                         <span class="stringliteral">&quot;mov           %5, %%bl \n\t&quot;</span>   <span class="comment">/* load NRightShift into BL */</span>
<a name="l06038"></a>06038                         <span class="stringliteral">&quot;movd      %%ebx, %%mm5 \n\t&quot;</span>   <span class="comment">/* copy NRightShift into MM5 */</span>
<a name="l06039"></a>06039                         <span class="stringliteral">&quot;mov          %4, %%edx \n\t&quot;</span>   <span class="comment">/* load Kernel address into EDX */</span>
<a name="l06040"></a>06040                         <span class="stringliteral">&quot;mov          %1, %%esi \n\t&quot;</span>   <span class="comment">/* load Src  address to ESI */</span>
<a name="l06041"></a>06041                         <span class="stringliteral">&quot;mov          %0, %%edi \n\t&quot;</span>   <span class="comment">/* load Dest address to EDI */</span>
<a name="l06042"></a>06042                         <span class="stringliteral">&quot;add          $3, %%edi \n\t&quot;</span>   <span class="comment">/* 3 column offset from the left edge */</span>
<a name="l06043"></a>06043                         <span class="stringliteral">&quot;mov          %3, %%eax \n\t&quot;</span>   <span class="comment">/* load columns into EAX */</span>
<a name="l06044"></a>06044                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span>   <span class="comment">/* 3 row offset from the top edge */</span>
<a name="l06045"></a>06045                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span> <span class="stringliteral">&quot;mov          %2, %%ebx \n\t&quot;</span>       <span class="comment">/* initialize ROWS counter */</span>
<a name="l06046"></a>06046                         <span class="stringliteral">&quot;sub          $6, %%ebx \n\t&quot;</span>   <span class="comment">/* do not use first 3 and last 3 rows */</span>
<a name="l06047"></a>06047                         <span class="comment">/* --- */</span>
<a name="l06048"></a>06048                         <span class="stringliteral">&quot;.L10380:               \n\t&quot;</span> <span class="stringliteral">&quot;mov       %%eax, %%ecx \n\t&quot;</span>     <span class="comment">/* initialize COLUMNS counter */</span>
<a name="l06049"></a>06049                         <span class="stringliteral">&quot;sub          $6, %%ecx \n\t&quot;</span>   <span class="comment">/* do not use first 3 and last 3 columns */</span>
<a name="l06050"></a>06050                         <span class="stringliteral">&quot;.align 16              \n\t&quot;</span>   <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l06051"></a>06051                         <span class="stringliteral">&quot;.L10382:               \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm7, %%mm7 \n\t&quot;</span>     <span class="comment">/* zero MM7 (accumulator) */</span>
<a name="l06052"></a>06052                         <span class="stringliteral">&quot;movd      %%esi, %%mm6 \n\t&quot;</span>   <span class="comment">/* save ESI in MM6 */</span>
<a name="l06053"></a>06053                         <span class="comment">/* --- 1 */</span>
<a name="l06054"></a>06054                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06055"></a>06055                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06056"></a>06056                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06057"></a>06057                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06058"></a>06058                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06059"></a>06059                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06060"></a>06060                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06061"></a>06061                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06062"></a>06062                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06063"></a>06063                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06064"></a>06064                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06065"></a>06065                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06066"></a>06066                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06067"></a>06067                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06068"></a>06068                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06069"></a>06069                         <span class="comment">/* --- 2 */</span>
<a name="l06070"></a>06070                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06071"></a>06071                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06072"></a>06072                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06073"></a>06073                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06074"></a>06074                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06075"></a>06075                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06076"></a>06076                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06077"></a>06077                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06078"></a>06078                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06079"></a>06079                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06080"></a>06080                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06081"></a>06081                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06082"></a>06082                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06083"></a>06083                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06084"></a>06084                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06085"></a>06085                         <span class="comment">/* --- 3 */</span>
<a name="l06086"></a>06086                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06087"></a>06087                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06088"></a>06088                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06089"></a>06089                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06090"></a>06090                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06091"></a>06091                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06092"></a>06092                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06093"></a>06093                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06094"></a>06094                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06095"></a>06095                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06096"></a>06096                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06097"></a>06097                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06098"></a>06098                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06099"></a>06099                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06100"></a>06100                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06101"></a>06101                         <span class="comment">/* --- 4 */</span>
<a name="l06102"></a>06102                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06103"></a>06103                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06104"></a>06104                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06105"></a>06105                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06106"></a>06106                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06107"></a>06107                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06108"></a>06108                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06109"></a>06109                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06110"></a>06110                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06111"></a>06111                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06112"></a>06112                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06113"></a>06113                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06114"></a>06114                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06115"></a>06115                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06116"></a>06116                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06117"></a>06117                         <span class="comment">/* --- 5 */</span>
<a name="l06118"></a>06118                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06119"></a>06119                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06120"></a>06120                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06121"></a>06121                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06122"></a>06122                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06123"></a>06123                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06124"></a>06124                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06125"></a>06125                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06126"></a>06126                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06127"></a>06127                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06128"></a>06128                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06129"></a>06129                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06130"></a>06130                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06131"></a>06131                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06132"></a>06132                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06133"></a>06133                         <span class="comment">/* --- 6 */</span>
<a name="l06134"></a>06134                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06135"></a>06135                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06136"></a>06136                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06137"></a>06137                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06138"></a>06138                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06139"></a>06139                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06140"></a>06140                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06141"></a>06141                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06142"></a>06142                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06143"></a>06143                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06144"></a>06144                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06145"></a>06145                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06146"></a>06146                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06147"></a>06147                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06148"></a>06148                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06149"></a>06149                         <span class="comment">/* --- 7 */</span>
<a name="l06150"></a>06150                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06151"></a>06151                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06152"></a>06152                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06153"></a>06153                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06154"></a>06154                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06155"></a>06155                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06156"></a>06156                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06157"></a>06157                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06158"></a>06158                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06159"></a>06159                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06160"></a>06160                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06161"></a>06161                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06162"></a>06162                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06163"></a>06163                         <span class="comment">/* --- */</span>
<a name="l06164"></a>06164                         <span class="stringliteral">&quot;movq      %%mm7, %%mm3 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l06165"></a>06165                         <span class="stringliteral">&quot;psrlq       $32, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l06166"></a>06166                         <span class="stringliteral">&quot;paddsw    %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l06167"></a>06167                         <span class="stringliteral">&quot;movq      %%mm7, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM2 */</span>
<a name="l06168"></a>06168                         <span class="stringliteral">&quot;psrlq       $16, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 1 left word to the right */</span>
<a name="l06169"></a>06169                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l06170"></a>06170                         <span class="stringliteral">&quot;movd      %%eax, %%mm1 \n\t&quot;</span>   <span class="comment">/* save EAX in MM1 */</span>
<a name="l06171"></a>06171                         <span class="stringliteral">&quot;packuswb  %%mm0, %%mm7 \n\t&quot;</span>   <span class="comment">/* pack division result with saturation */</span>
<a name="l06172"></a>06172                         <span class="stringliteral">&quot;movd      %%mm7, %%eax \n\t&quot;</span>   <span class="comment">/* copy saturated result into EAX */</span>
<a name="l06173"></a>06173                         <span class="stringliteral">&quot;mov      %%al, (%%edi) \n\t&quot;</span>   <span class="comment">/* copy a byte result into Dest */</span>
<a name="l06174"></a>06174                         <span class="stringliteral">&quot;movd      %%mm1, %%eax \n\t&quot;</span>   <span class="comment">/* restore saved EAX */</span>
<a name="l06175"></a>06175                         <span class="comment">/* -- */</span>
<a name="l06176"></a>06176                         <span class="stringliteral">&quot;movd      %%mm6, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer to the top pixel */</span>
<a name="l06177"></a>06177                         <span class="stringliteral">&quot;sub        $104, %%edx \n\t&quot;</span>   <span class="comment">/* EDX = Kernel address */</span>
<a name="l06178"></a>06178                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l06179"></a>06179                         <span class="stringliteral">&quot;inc              %%edi \n\t&quot;</span>   <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l06180"></a>06180                         <span class="comment">/* --- */</span>
<a name="l06181"></a>06181                         <span class="stringliteral">&quot;dec              %%ecx \n\t&quot;</span>   <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l06182"></a>06182                         <span class="stringliteral">&quot;jnz            .L10382 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l06183"></a>06183                         <span class="stringliteral">&quot;add          $6, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row in Src */</span>
<a name="l06184"></a>06184                         <span class="stringliteral">&quot;add          $6, %%edi \n\t&quot;</span>   <span class="comment">/* move to the next row in Dest */</span>
<a name="l06185"></a>06185                         <span class="stringliteral">&quot;dec              %%ebx \n\t&quot;</span>   <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l06186"></a>06186                         <span class="stringliteral">&quot;jnz            .L10380 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l06187"></a>06187                         <span class="comment">/* --- */</span>
<a name="l06188"></a>06188                         <span class="stringliteral">&quot;emms                   \n\t&quot;</span>   <span class="comment">/* exit MMX state */</span>
<a name="l06189"></a>06189                         <span class="stringliteral">&quot;popa                   \n\t&quot;</span>:<span class="stringliteral">&quot;=m&quot;</span> (Dest)       <span class="comment">/* %0 */</span>
<a name="l06190"></a>06190                         :<span class="stringliteral">&quot;m&quot;</span>(Src),              <span class="comment">/* %1 */</span>
<a name="l06191"></a>06191                         <span class="stringliteral">&quot;m&quot;</span>(rows),              <span class="comment">/* %2 */</span>
<a name="l06192"></a>06192                         <span class="stringliteral">&quot;m&quot;</span>(columns),           <span class="comment">/* %3 */</span>
<a name="l06193"></a>06193                         <span class="stringliteral">&quot;m&quot;</span>(Kernel),            <span class="comment">/* %4 */</span>
<a name="l06194"></a>06194                         <span class="stringliteral">&quot;m&quot;</span>(NRightShift)        <span class="comment">/* %5 */</span>
<a name="l06195"></a>06195                         );
<a name="l06196"></a>06196 <span class="preprocessor">#endif</span>
<a name="l06197"></a>06197 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l06198"></a>06198 <span class="preprocessor"></span>                <span class="keywordflow">return</span> (0);
<a name="l06199"></a>06199         } <span class="keywordflow">else</span> {
<a name="l06200"></a>06200                 <span class="comment">/* No non-MMX implementation yet */</span>
<a name="l06201"></a>06201                 <span class="keywordflow">return</span> (-1);
<a name="l06202"></a>06202         }
<a name="l06203"></a>06203 }
<a name="l06204"></a>06204 
<a name="l06219"></a><a class="code" href="_s_d_l2__image_filter_8c.html#a6aaa30dc51d1e51585d02d123b0f1a7a">06219</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a6aaa30dc51d1e51585d02d123b0f1a7a" title="Filter using ConvolveKernel9x9ShiftRight: Dij = saturation255( ... )">SDL_imageFilterConvolveKernel9x9ShiftRight</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">int</span> rows, <span class="keywordtype">int</span> columns,
<a name="l06220"></a>06220                                                                                            <span class="keywordtype">signed</span> <span class="keywordtype">short</span> *Kernel, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> NRightShift)
<a name="l06221"></a>06221 {
<a name="l06222"></a>06222         <span class="comment">/* Validate input parameters */</span>
<a name="l06223"></a>06223         <span class="keywordflow">if</span> ((Src == NULL) || (Dest == NULL) || (Kernel == NULL))
<a name="l06224"></a>06224                 <span class="keywordflow">return</span>(-1);
<a name="l06225"></a>06225 
<a name="l06226"></a>06226         <span class="keywordflow">if</span> ((columns &lt; 9) || (rows &lt; 9) || (NRightShift &gt; 7))
<a name="l06227"></a>06227                 <span class="keywordflow">return</span> (-1);
<a name="l06228"></a>06228 
<a name="l06229"></a>06229         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>())) {
<a name="l06230"></a>06230 <span class="comment">//#ifdef USE_MMX</span>
<a name="l06231"></a>06231 <span class="preprocessor">#if defined(USE_MMX) &amp;&amp; defined(i386)</span>
<a name="l06232"></a>06232 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l06233"></a>06233 <span class="preprocessor"></span>                __asm
<a name="l06234"></a>06234                 {
<a name="l06235"></a>06235                         pusha
<a name="l06236"></a>06236                                 pxor mm0, mm0           <span class="comment">/* zero MM0 */</span>
<a name="l06237"></a>06237                                 xor ebx, ebx    <span class="comment">/* zero EBX */</span>
<a name="l06238"></a>06238                                 mov bl, NRightShift     <span class="comment">/* load NRightShift into BL */</span>
<a name="l06239"></a>06239                                 movd mm5, ebx           <span class="comment">/* copy NRightShift into MM5 */</span>
<a name="l06240"></a>06240                                 mov edx, Kernel         <span class="comment">/* load Kernel address into EDX */</span>
<a name="l06241"></a>06241                                 mov esi, Src    <span class="comment">/* load Src  address to ESI */</span>
<a name="l06242"></a>06242                                 mov edi, Dest           <span class="comment">/* load Dest address to EDI */</span>
<a name="l06243"></a>06243                                 add edi, 4      <span class="comment">/* 4 column offset from the left edge */</span>
<a name="l06244"></a>06244                                 mov eax, columns        <span class="comment">/* load columns into EAX */</span>
<a name="l06245"></a>06245                                 add edi, eax    <span class="comment">/* 4 row offset from the top edge */</span>
<a name="l06246"></a>06246                                 add edi, eax
<a name="l06247"></a>06247                                 add edi, eax
<a name="l06248"></a>06248                                 add edi, eax
<a name="l06249"></a>06249                                 mov ebx, rows           <span class="comment">/* initialize ROWS counter */</span>
<a name="l06250"></a>06250                                 sub ebx, 8      <span class="comment">/* do not use first 4 and last 4 rows */</span>
<a name="l06251"></a>06251                                 <span class="comment">/* ---, */</span>
<a name="l06252"></a>06252 L10390:
<a name="l06253"></a>06253                         mov ecx, eax    <span class="comment">/* initialize COLUMNS counter */</span>
<a name="l06254"></a>06254                                 sub ecx, 8      <span class="comment">/* do not use first 4 and last 4 columns */</span>
<a name="l06255"></a>06255                                 align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l06256"></a>06256 L10392:
<a name="l06257"></a>06257                         pxor mm7, mm7           <span class="comment">/* zero MM7 (accumulator) */</span>
<a name="l06258"></a>06258                                 movd mm6, esi           <span class="comment">/* save ESI in MM6 */</span>
<a name="l06259"></a>06259                                 <span class="comment">/* --- 1 */</span>
<a name="l06260"></a>06260                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06261"></a>06261                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06262"></a>06262                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06263"></a>06263                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06264"></a>06264                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06265"></a>06265                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06266"></a>06266                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06267"></a>06267                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06268"></a>06268                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06269"></a>06269                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06270"></a>06270                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06271"></a>06271                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06272"></a>06272                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l06273"></a>06273                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06274"></a>06274                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06275"></a>06275                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06276"></a>06276                         dec              esi
<a name="l06277"></a>06277                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06278"></a>06278                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06279"></a>06279                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06280"></a>06280                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06281"></a>06281                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06282"></a>06282                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06283"></a>06283                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06284"></a>06284                                 <span class="comment">/* --- 2 */</span>
<a name="l06285"></a>06285                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06286"></a>06286                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06287"></a>06287                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06288"></a>06288                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06289"></a>06289                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06290"></a>06290                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06291"></a>06291                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06292"></a>06292                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06293"></a>06293                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06294"></a>06294                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06295"></a>06295                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06296"></a>06296                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06297"></a>06297                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l06298"></a>06298                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06299"></a>06299                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06300"></a>06300                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06301"></a>06301                         dec              esi
<a name="l06302"></a>06302                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06303"></a>06303                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06304"></a>06304                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06305"></a>06305                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06306"></a>06306                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06307"></a>06307                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06308"></a>06308                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06309"></a>06309                                 <span class="comment">/* --- 3 */</span>
<a name="l06310"></a>06310                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06311"></a>06311                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06312"></a>06312                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06313"></a>06313                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06314"></a>06314                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06315"></a>06315                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06316"></a>06316                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06317"></a>06317                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06318"></a>06318                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06319"></a>06319                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06320"></a>06320                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06321"></a>06321                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06322"></a>06322                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l06323"></a>06323                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06324"></a>06324                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06325"></a>06325                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06326"></a>06326                         dec              esi
<a name="l06327"></a>06327                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06328"></a>06328                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06329"></a>06329                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06330"></a>06330                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06331"></a>06331                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06332"></a>06332                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06333"></a>06333                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06334"></a>06334                                 <span class="comment">/* --- 4 */</span>
<a name="l06335"></a>06335                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06336"></a>06336                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06337"></a>06337                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06338"></a>06338                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06339"></a>06339                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06340"></a>06340                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06341"></a>06341                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06342"></a>06342                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06343"></a>06343                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06344"></a>06344                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06345"></a>06345                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06346"></a>06346                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06347"></a>06347                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l06348"></a>06348                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06349"></a>06349                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06350"></a>06350                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06351"></a>06351                         dec              esi
<a name="l06352"></a>06352                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06353"></a>06353                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06354"></a>06354                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06355"></a>06355                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06356"></a>06356                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06357"></a>06357                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06358"></a>06358                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06359"></a>06359                                 <span class="comment">/* --- 5 */</span>
<a name="l06360"></a>06360                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06361"></a>06361                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06362"></a>06362                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06363"></a>06363                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06364"></a>06364                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06365"></a>06365                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06366"></a>06366                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06367"></a>06367                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06368"></a>06368                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06369"></a>06369                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06370"></a>06370                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06371"></a>06371                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06372"></a>06372                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l06373"></a>06373                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06374"></a>06374                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06375"></a>06375                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06376"></a>06376                         dec              esi
<a name="l06377"></a>06377                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06378"></a>06378                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06379"></a>06379                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06380"></a>06380                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06381"></a>06381                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06382"></a>06382                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06383"></a>06383                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06384"></a>06384                                 <span class="comment">/* --- 6 */</span>
<a name="l06385"></a>06385                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06386"></a>06386                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06387"></a>06387                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06388"></a>06388                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06389"></a>06389                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06390"></a>06390                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06391"></a>06391                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06392"></a>06392                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06393"></a>06393                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06394"></a>06394                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06395"></a>06395                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06396"></a>06396                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06397"></a>06397                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l06398"></a>06398                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06399"></a>06399                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06400"></a>06400                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06401"></a>06401                         dec              esi
<a name="l06402"></a>06402                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06403"></a>06403                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06404"></a>06404                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06405"></a>06405                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06406"></a>06406                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06407"></a>06407                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06408"></a>06408                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06409"></a>06409                                 <span class="comment">/* --- 7 */</span>
<a name="l06410"></a>06410                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06411"></a>06411                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06412"></a>06412                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06413"></a>06413                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06414"></a>06414                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06415"></a>06415                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06416"></a>06416                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06417"></a>06417                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06418"></a>06418                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06419"></a>06419                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06420"></a>06420                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06421"></a>06421                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06422"></a>06422                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l06423"></a>06423                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06424"></a>06424                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06425"></a>06425                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06426"></a>06426                         dec              esi
<a name="l06427"></a>06427                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06428"></a>06428                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06429"></a>06429                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06430"></a>06430                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06431"></a>06431                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06432"></a>06432                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06433"></a>06433                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06434"></a>06434                                 <span class="comment">/* --- 8 */</span>
<a name="l06435"></a>06435                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06436"></a>06436                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06437"></a>06437                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06438"></a>06438                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06439"></a>06439                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06440"></a>06440                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06441"></a>06441                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06442"></a>06442                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06443"></a>06443                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06444"></a>06444                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06445"></a>06445                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06446"></a>06446                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06447"></a>06447                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l06448"></a>06448                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06449"></a>06449                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06450"></a>06450                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06451"></a>06451                         dec              esi
<a name="l06452"></a>06452                                 add esi, eax    <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06453"></a>06453                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06454"></a>06454                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06455"></a>06455                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06456"></a>06456                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06457"></a>06457                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06458"></a>06458                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06459"></a>06459                                 <span class="comment">/* --- 9 */</span>
<a name="l06460"></a>06460                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06461"></a>06461                         movq mm2, mm1           <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06462"></a>06462                                 inc              esi            <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06463"></a>06463                                 movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06464"></a>06464                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06465"></a>06465                                 movq mm4, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06466"></a>06466                         add edx, 8      <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06467"></a>06467                                 punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06468"></a>06468                                 punpckhbw mm2, mm0      <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06469"></a>06469                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06470"></a>06470                                 psrlw mm2, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06471"></a>06471                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06472"></a>06472                                 pmullw mm2, mm4         <span class="comment">/* mult 4 high words of Src and Kernel */</span>
<a name="l06473"></a>06473                                 paddsw mm1, mm2         <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06474"></a>06474                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06475"></a>06475                                 movq mm1, [esi]         <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06476"></a>06476                         movq mm3, [edx]         <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06477"></a>06477                         punpcklbw mm1, mm0      <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06478"></a>06478                                 psrlw mm1, mm5          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06479"></a>06479                                 pmullw mm1, mm3         <span class="comment">/* mult 4 low  words of Src and Kernel */</span>
<a name="l06480"></a>06480                                 paddsw mm7, mm1         <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06481"></a>06481                                 <span class="comment">/* ---, */</span>
<a name="l06482"></a>06482                                 movq mm3, mm7           <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l06483"></a>06483                                 psrlq mm7, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l06484"></a>06484                                 paddsw mm7, mm3         <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l06485"></a>06485                                 movq mm2, mm7           <span class="comment">/* copy MM7 into MM2 */</span>
<a name="l06486"></a>06486                                 psrlq mm7, 16           <span class="comment">/* shift 1 left word to the right */</span>
<a name="l06487"></a>06487                                 paddsw mm7, mm2         <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l06488"></a>06488                                 movd mm1, eax           <span class="comment">/* save EAX in MM1 */</span>
<a name="l06489"></a>06489                                 packuswb mm7, mm0       <span class="comment">/* pack division result with saturation */</span>
<a name="l06490"></a>06490                                 movd eax, mm7           <span class="comment">/* copy saturated result into EAX */</span>
<a name="l06491"></a>06491                                 mov [edi], al           <span class="comment">/* copy a byte result into Dest */</span>
<a name="l06492"></a>06492                                 movd eax, mm1           <span class="comment">/* restore saved EAX */</span>
<a name="l06493"></a>06493                                 <span class="comment">/* --, */</span>
<a name="l06494"></a>06494                                 movd esi, mm6           <span class="comment">/* move Src pointer to the top pixel */</span>
<a name="l06495"></a>06495                                 sub edx, 208    <span class="comment">/* EDX = Kernel address */</span>
<a name="l06496"></a>06496                                 inc              esi            <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l06497"></a>06497                                 inc              edi            <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l06498"></a>06498                                 <span class="comment">/* ---, */</span>
<a name="l06499"></a>06499                                 dec              ecx            <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l06500"></a>06500                                 jnz            L10392           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l06501"></a>06501                                 add esi, 8      <span class="comment">/* move to the next row in Src */</span>
<a name="l06502"></a>06502                                 add edi, 8      <span class="comment">/* move to the next row in Dest */</span>
<a name="l06503"></a>06503                                 dec              ebx            <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l06504"></a>06504                                 jnz            L10390           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l06505"></a>06505                                 <span class="comment">/* ---, */</span>
<a name="l06506"></a>06506                                 emms                            <span class="comment">/* exit MMX state */</span>
<a name="l06507"></a>06507                                 popa
<a name="l06508"></a>06508                 }
<a name="l06509"></a>06509 <span class="preprocessor">#else</span>
<a name="l06510"></a>06510 <span class="preprocessor"></span>                <span class="keyword">asm</span> <span class="keyword">volatile</span>
<a name="l06511"></a>06511                         (<span class="stringliteral">&quot;pusha              \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm0, %%mm0 \n\t&quot;</span>        <span class="comment">/* zero MM0 */</span>
<a name="l06512"></a>06512                         <span class="stringliteral">&quot;xor       %%ebx, %%ebx \n\t&quot;</span>   <span class="comment">/* zero EBX */</span>
<a name="l06513"></a>06513                         <span class="stringliteral">&quot;mov           %5, %%bl \n\t&quot;</span>   <span class="comment">/* load NRightShift into BL */</span>
<a name="l06514"></a>06514                         <span class="stringliteral">&quot;movd      %%ebx, %%mm5 \n\t&quot;</span>   <span class="comment">/* copy NRightShift into MM5 */</span>
<a name="l06515"></a>06515                         <span class="stringliteral">&quot;mov          %4, %%edx \n\t&quot;</span>   <span class="comment">/* load Kernel address into EDX */</span>
<a name="l06516"></a>06516                         <span class="stringliteral">&quot;mov          %1, %%esi \n\t&quot;</span>   <span class="comment">/* load Src  address to ESI */</span>
<a name="l06517"></a>06517                         <span class="stringliteral">&quot;mov          %0, %%edi \n\t&quot;</span>   <span class="comment">/* load Dest address to EDI */</span>
<a name="l06518"></a>06518                         <span class="stringliteral">&quot;add          $4, %%edi \n\t&quot;</span>   <span class="comment">/* 4 column offset from the left edge */</span>
<a name="l06519"></a>06519                         <span class="stringliteral">&quot;mov          %3, %%eax \n\t&quot;</span>   <span class="comment">/* load columns into EAX */</span>
<a name="l06520"></a>06520                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span>   <span class="comment">/* 4 row offset from the top edge */</span>
<a name="l06521"></a>06521                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span> <span class="stringliteral">&quot;mov          %2, %%ebx \n\t&quot;</span> <span class="comment">/* initialize ROWS counter */</span>
<a name="l06522"></a>06522                         <span class="stringliteral">&quot;sub          $8, %%ebx \n\t&quot;</span>   <span class="comment">/* do not use first 4 and last 4 rows */</span>
<a name="l06523"></a>06523                         <span class="comment">/* --- */</span>
<a name="l06524"></a>06524                         <span class="stringliteral">&quot;.L10390:               \n\t&quot;</span> <span class="stringliteral">&quot;mov       %%eax, %%ecx \n\t&quot;</span>     <span class="comment">/* initialize COLUMNS counter */</span>
<a name="l06525"></a>06525                         <span class="stringliteral">&quot;sub          $8, %%ecx \n\t&quot;</span>   <span class="comment">/* do not use first 4 and last 4 columns */</span>
<a name="l06526"></a>06526                         <span class="stringliteral">&quot;.align 16              \n\t&quot;</span>   <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l06527"></a>06527                         <span class="stringliteral">&quot;.L10392:               \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm7, %%mm7 \n\t&quot;</span>     <span class="comment">/* zero MM7 (accumulator) */</span>
<a name="l06528"></a>06528                         <span class="stringliteral">&quot;movd      %%esi, %%mm6 \n\t&quot;</span>   <span class="comment">/* save ESI in MM6 */</span>
<a name="l06529"></a>06529                         <span class="comment">/* --- 1 */</span>
<a name="l06530"></a>06530                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06531"></a>06531                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06532"></a>06532                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06533"></a>06533                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06534"></a>06534                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06535"></a>06535                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06536"></a>06536                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06537"></a>06537                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06538"></a>06538                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06539"></a>06539                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06540"></a>06540                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06541"></a>06541                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06542"></a>06542                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06543"></a>06543                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06544"></a>06544                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06545"></a>06545                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06546"></a>06546                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06547"></a>06547                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06548"></a>06548                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06549"></a>06549                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06550"></a>06550                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06551"></a>06551                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06552"></a>06552                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06553"></a>06553                         <span class="comment">/* --- 2 */</span>
<a name="l06554"></a>06554                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06555"></a>06555                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06556"></a>06556                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06557"></a>06557                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06558"></a>06558                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06559"></a>06559                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06560"></a>06560                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06561"></a>06561                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06562"></a>06562                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06563"></a>06563                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06564"></a>06564                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06565"></a>06565                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06566"></a>06566                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06567"></a>06567                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06568"></a>06568                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06569"></a>06569                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06570"></a>06570                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06571"></a>06571                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06572"></a>06572                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06573"></a>06573                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06574"></a>06574                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06575"></a>06575                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06576"></a>06576                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06577"></a>06577                         <span class="comment">/* --- 3 */</span>
<a name="l06578"></a>06578                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06579"></a>06579                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06580"></a>06580                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06581"></a>06581                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06582"></a>06582                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06583"></a>06583                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06584"></a>06584                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06585"></a>06585                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06586"></a>06586                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06587"></a>06587                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06588"></a>06588                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06589"></a>06589                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06590"></a>06590                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06591"></a>06591                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06592"></a>06592                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06593"></a>06593                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06594"></a>06594                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06595"></a>06595                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06596"></a>06596                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06597"></a>06597                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06598"></a>06598                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06599"></a>06599                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06600"></a>06600                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06601"></a>06601                         <span class="comment">/* --- 4 */</span>
<a name="l06602"></a>06602                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06603"></a>06603                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06604"></a>06604                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06605"></a>06605                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06606"></a>06606                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06607"></a>06607                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06608"></a>06608                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06609"></a>06609                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06610"></a>06610                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06611"></a>06611                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06612"></a>06612                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06613"></a>06613                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06614"></a>06614                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06615"></a>06615                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06616"></a>06616                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06617"></a>06617                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06618"></a>06618                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06619"></a>06619                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06620"></a>06620                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06621"></a>06621                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06622"></a>06622                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06623"></a>06623                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06624"></a>06624                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06625"></a>06625                         <span class="comment">/* --- 5 */</span>
<a name="l06626"></a>06626                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06627"></a>06627                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06628"></a>06628                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06629"></a>06629                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06630"></a>06630                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06631"></a>06631                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06632"></a>06632                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06633"></a>06633                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06634"></a>06634                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06635"></a>06635                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06636"></a>06636                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06637"></a>06637                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06638"></a>06638                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06639"></a>06639                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06640"></a>06640                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06641"></a>06641                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06642"></a>06642                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06643"></a>06643                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06644"></a>06644                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06645"></a>06645                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06646"></a>06646                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06647"></a>06647                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06648"></a>06648                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06649"></a>06649                         <span class="comment">/* --- 6 */</span>
<a name="l06650"></a>06650                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06651"></a>06651                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06652"></a>06652                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06653"></a>06653                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06654"></a>06654                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06655"></a>06655                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06656"></a>06656                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06657"></a>06657                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06658"></a>06658                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06659"></a>06659                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06660"></a>06660                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06661"></a>06661                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06662"></a>06662                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06663"></a>06663                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06664"></a>06664                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06665"></a>06665                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06666"></a>06666                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06667"></a>06667                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06668"></a>06668                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06669"></a>06669                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06670"></a>06670                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06671"></a>06671                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06672"></a>06672                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06673"></a>06673                         <span class="comment">/* --- 7 */</span>
<a name="l06674"></a>06674                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06675"></a>06675                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06676"></a>06676                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06677"></a>06677                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06678"></a>06678                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06679"></a>06679                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06680"></a>06680                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06681"></a>06681                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06682"></a>06682                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06683"></a>06683                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06684"></a>06684                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06685"></a>06685                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06686"></a>06686                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06687"></a>06687                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06688"></a>06688                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06689"></a>06689                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06690"></a>06690                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06691"></a>06691                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06692"></a>06692                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06693"></a>06693                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06694"></a>06694                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06695"></a>06695                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06696"></a>06696                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06697"></a>06697                         <span class="comment">/* --- 8 */</span>
<a name="l06698"></a>06698                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06699"></a>06699                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06700"></a>06700                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06701"></a>06701                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06702"></a>06702                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06703"></a>06703                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06704"></a>06704                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06705"></a>06705                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06706"></a>06706                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06707"></a>06707                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06708"></a>06708                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06709"></a>06709                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06710"></a>06710                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06711"></a>06711                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06712"></a>06712                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06713"></a>06713                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06714"></a>06714                         <span class="stringliteral">&quot;dec              %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>     <span class="comment">/* move Src pointer 1 row below */</span>
<a name="l06715"></a>06715                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06716"></a>06716                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06717"></a>06717                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06718"></a>06718                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06719"></a>06719                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06720"></a>06720                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06721"></a>06721                         <span class="comment">/* --- 9 */</span>
<a name="l06722"></a>06722                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06723"></a>06723                         <span class="stringliteral">&quot;movq      %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM1 into MM2 */</span>
<a name="l06724"></a>06724                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move pointer to the next 8 bytes of Src */</span>
<a name="l06725"></a>06725                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06726"></a>06726                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06727"></a>06727                         <span class="stringliteral">&quot;movq    (%%edx), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06728"></a>06728                         <span class="stringliteral">&quot;add          $8, %%edx \n\t&quot;</span>   <span class="comment">/* move pointer to other 4 words */</span>
<a name="l06729"></a>06729                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06730"></a>06730                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack second 4 bytes into words */</span>
<a name="l06731"></a>06731                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06732"></a>06732                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06733"></a>06733                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06734"></a>06734                         <span class="stringliteral">&quot;pmullw    %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* mult. 4 high words of Src and Kernel */</span>
<a name="l06735"></a>06735                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm1 \n\t&quot;</span>   <span class="comment">/* add 4 words of the high and low bytes */</span>
<a name="l06736"></a>06736                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06737"></a>06737                         <span class="stringliteral">&quot;movq    (%%esi), %%mm1 \n\t&quot;</span>   <span class="comment">/* load 8 bytes of the Src */</span>
<a name="l06738"></a>06738                         <span class="stringliteral">&quot;movq    (%%edx), %%mm3 \n\t&quot;</span>   <span class="comment">/* load 4 words of Kernel */</span>
<a name="l06739"></a>06739                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm1 \n\t&quot;</span>   <span class="comment">/* unpack first  4 bytes into words */</span>
<a name="l06740"></a>06740                         <span class="stringliteral">&quot;psrlw     %%mm5, %%mm1 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l06741"></a>06741                         <span class="stringliteral">&quot;pmullw    %%mm3, %%mm1 \n\t&quot;</span>   <span class="comment">/* mult. 4 low  words of Src and Kernel */</span>
<a name="l06742"></a>06742                         <span class="stringliteral">&quot;paddsw    %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* add MM1 to accumulator MM7 */</span>
<a name="l06743"></a>06743                         <span class="comment">/* --- */</span>
<a name="l06744"></a>06744                         <span class="stringliteral">&quot;movq      %%mm7, %%mm3 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l06745"></a>06745                         <span class="stringliteral">&quot;psrlq       $32, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l06746"></a>06746                         <span class="stringliteral">&quot;paddsw    %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 2 left and 2 right result words */</span>
<a name="l06747"></a>06747                         <span class="stringliteral">&quot;movq      %%mm7, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM2 */</span>
<a name="l06748"></a>06748                         <span class="stringliteral">&quot;psrlq       $16, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 1 left word to the right */</span>
<a name="l06749"></a>06749                         <span class="stringliteral">&quot;paddsw    %%mm2, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 1 left and 1 right result words */</span>
<a name="l06750"></a>06750                         <span class="stringliteral">&quot;movd      %%eax, %%mm1 \n\t&quot;</span>   <span class="comment">/* save EAX in MM1 */</span>
<a name="l06751"></a>06751                         <span class="stringliteral">&quot;packuswb  %%mm0, %%mm7 \n\t&quot;</span>   <span class="comment">/* pack division result with saturation */</span>
<a name="l06752"></a>06752                         <span class="stringliteral">&quot;movd      %%mm7, %%eax \n\t&quot;</span>   <span class="comment">/* copy saturated result into EAX */</span>
<a name="l06753"></a>06753                         <span class="stringliteral">&quot;mov      %%al, (%%edi) \n\t&quot;</span>   <span class="comment">/* copy a byte result into Dest */</span>
<a name="l06754"></a>06754                         <span class="stringliteral">&quot;movd      %%mm1, %%eax \n\t&quot;</span>   <span class="comment">/* restore saved EAX */</span>
<a name="l06755"></a>06755                         <span class="comment">/* -- */</span>
<a name="l06756"></a>06756                         <span class="stringliteral">&quot;movd      %%mm6, %%esi \n\t&quot;</span>   <span class="comment">/* move Src pointer to the top pixel */</span>
<a name="l06757"></a>06757                         <span class="stringliteral">&quot;sub        $208, %%edx \n\t&quot;</span>   <span class="comment">/* EDX = Kernel address */</span>
<a name="l06758"></a>06758                         <span class="stringliteral">&quot;inc              %%esi \n\t&quot;</span>   <span class="comment">/* move Src  pointer to the next pixel */</span>
<a name="l06759"></a>06759                         <span class="stringliteral">&quot;inc              %%edi \n\t&quot;</span>   <span class="comment">/* move Dest pointer to the next pixel */</span>
<a name="l06760"></a>06760                         <span class="comment">/* --- */</span>
<a name="l06761"></a>06761                         <span class="stringliteral">&quot;dec              %%ecx \n\t&quot;</span>   <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l06762"></a>06762                         <span class="stringliteral">&quot;jnz            .L10392 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l06763"></a>06763                         <span class="stringliteral">&quot;add          $8, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row in Src */</span>
<a name="l06764"></a>06764                         <span class="stringliteral">&quot;add          $8, %%edi \n\t&quot;</span>   <span class="comment">/* move to the next row in Dest */</span>
<a name="l06765"></a>06765                         <span class="stringliteral">&quot;dec              %%ebx \n\t&quot;</span>   <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l06766"></a>06766                         <span class="stringliteral">&quot;jnz            .L10390 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l06767"></a>06767                         <span class="comment">/* --- */</span>
<a name="l06768"></a>06768                         <span class="stringliteral">&quot;emms                   \n\t&quot;</span>   <span class="comment">/* exit MMX state */</span>
<a name="l06769"></a>06769                         <span class="stringliteral">&quot;popa                   \n\t&quot;</span>:<span class="stringliteral">&quot;=m&quot;</span> (Dest)       <span class="comment">/* %0 */</span>
<a name="l06770"></a>06770                         :<span class="stringliteral">&quot;m&quot;</span>(Src),              <span class="comment">/* %1 */</span>
<a name="l06771"></a>06771                         <span class="stringliteral">&quot;m&quot;</span>(rows),              <span class="comment">/* %2 */</span>
<a name="l06772"></a>06772                         <span class="stringliteral">&quot;m&quot;</span>(columns),           <span class="comment">/* %3 */</span>
<a name="l06773"></a>06773                         <span class="stringliteral">&quot;m&quot;</span>(Kernel),            <span class="comment">/* %4 */</span>
<a name="l06774"></a>06774                         <span class="stringliteral">&quot;m&quot;</span>(NRightShift)        <span class="comment">/* %5 */</span>
<a name="l06775"></a>06775                         );
<a name="l06776"></a>06776 <span class="preprocessor">#endif</span>
<a name="l06777"></a>06777 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l06778"></a>06778 <span class="preprocessor"></span>                <span class="keywordflow">return</span> (0);
<a name="l06779"></a>06779         } <span class="keywordflow">else</span> {
<a name="l06780"></a>06780                 <span class="comment">/* No non-MMX implementation yet */</span>
<a name="l06781"></a>06781                 <span class="keywordflow">return</span> (-1);
<a name="l06782"></a>06782         }
<a name="l06783"></a>06783 }
<a name="l06784"></a>06784 
<a name="l06785"></a>06785 <span class="comment">/* ------------------------------------------------------------------------------------ */</span>
<a name="l06786"></a>06786 
<a name="l06799"></a><a class="code" href="_s_d_l2__image_filter_8c.html#a015fe05161b701162d9ecffb01413f1e">06799</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a015fe05161b701162d9ecffb01413f1e" title="Filter using SobelX: Dij = saturation255( ... )">SDL_imageFilterSobelX</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">int</span> rows, <span class="keywordtype">int</span> columns)
<a name="l06800"></a>06800 {
<a name="l06801"></a>06801         <span class="comment">/* Validate input parameters */</span>
<a name="l06802"></a>06802         <span class="keywordflow">if</span> ((Src == NULL) || (Dest == NULL))
<a name="l06803"></a>06803                 <span class="keywordflow">return</span>(-1);
<a name="l06804"></a>06804 
<a name="l06805"></a>06805         <span class="keywordflow">if</span> ((columns &lt; 8) || (rows &lt; 3))
<a name="l06806"></a>06806                 <span class="keywordflow">return</span> (-1);
<a name="l06807"></a>06807 
<a name="l06808"></a>06808         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>())) {
<a name="l06809"></a>06809 <span class="comment">//#ifdef USE_MMX</span>
<a name="l06810"></a>06810 <span class="preprocessor">#if defined(USE_MMX) &amp;&amp; defined(i386)</span>
<a name="l06811"></a>06811 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l06812"></a>06812 <span class="preprocessor"></span>                __asm
<a name="l06813"></a>06813                 {
<a name="l06814"></a>06814                         pusha
<a name="l06815"></a>06815                                 pxor mm0, mm0           <span class="comment">/* zero MM0 */</span>
<a name="l06816"></a>06816                                 mov eax, columns        <span class="comment">/* load columns into EAX */</span>
<a name="l06817"></a>06817                                 <span class="comment">/* ---, */</span>
<a name="l06818"></a>06818                                 mov esi, Src    <span class="comment">/* ESI = Src row 0 address */</span>
<a name="l06819"></a>06819                                 mov edi, Dest           <span class="comment">/* load Dest address to EDI */</span>
<a name="l06820"></a>06820                                 add edi, eax    <span class="comment">/* EDI = EDI + columns */</span>
<a name="l06821"></a>06821                                 inc              edi            <span class="comment">/* 1 byte offset from the left edge */</span>
<a name="l06822"></a>06822                                 mov edx, rows           <span class="comment">/* initialize ROWS counter */</span>
<a name="l06823"></a>06823                                 sub edx, 2      <span class="comment">/* do not use first and last rows */</span>
<a name="l06824"></a>06824                                 <span class="comment">/* ---, */</span>
<a name="l06825"></a>06825 L10400:
<a name="l06826"></a>06826                         mov ecx, eax    <span class="comment">/* initialize COLUMS counter */</span>
<a name="l06827"></a>06827                                 shr ecx, 3      <span class="comment">/* EBX/8 (MMX loads 8 bytes at a time) */</span>
<a name="l06828"></a>06828                                 mov ebx, esi    <span class="comment">/* save ESI in EBX */</span>
<a name="l06829"></a>06829                                 movd mm1, edi           <span class="comment">/* save EDI in MM1 */</span>
<a name="l06830"></a>06830                                 align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l06831"></a>06831 L10402:
<a name="l06832"></a>06832                         <span class="comment">/* ---, */</span>
<a name="l06833"></a>06833                         movq mm4, [esi]         <span class="comment">/* load 8 bytes from Src */</span>
<a name="l06834"></a>06834                         movq mm5, mm4           <span class="comment">/* save MM4 in MM5 */</span>
<a name="l06835"></a>06835                                 add esi, 2      <span class="comment">/* move ESI pointer 2 bytes right */</span>
<a name="l06836"></a>06836                                 punpcklbw mm4, mm0      <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l06837"></a>06837                                 punpckhbw mm5, mm0      <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l06838"></a>06838                                 movq mm6, [esi]         <span class="comment">/* load 8 bytes from Src */</span>
<a name="l06839"></a>06839                         movq mm7, mm6           <span class="comment">/* save MM6 in MM7 */</span>
<a name="l06840"></a>06840                                 sub esi, 2      <span class="comment">/* move ESI pointer back 2 bytes left */</span>
<a name="l06841"></a>06841                                 punpcklbw mm6, mm0      <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l06842"></a>06842                                 punpckhbw mm7, mm0      <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l06843"></a>06843                                 add esi, eax    <span class="comment">/* move to the next row of Src */</span>
<a name="l06844"></a>06844                                 movq mm2, [esi]         <span class="comment">/* load 8 bytes from Src */</span>
<a name="l06845"></a>06845                         movq mm3, mm2           <span class="comment">/* save MM2 in MM3 */</span>
<a name="l06846"></a>06846                                 add esi, 2      <span class="comment">/* move ESI pointer 2 bytes right */</span>
<a name="l06847"></a>06847                                 punpcklbw mm2, mm0      <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l06848"></a>06848                                 punpckhbw mm3, mm0      <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l06849"></a>06849                                 paddw mm4, mm2          <span class="comment">/* add 4 low  bytes to accumolator MM4 */</span>
<a name="l06850"></a>06850                                 paddw mm5, mm3          <span class="comment">/* add 4 high bytes to accumolator MM5 */</span>
<a name="l06851"></a>06851                                 paddw mm4, mm2          <span class="comment">/* add 4 low  bytes to accumolator MM4 */</span>
<a name="l06852"></a>06852                                 paddw mm5, mm3          <span class="comment">/* add 4 high bytes to accumolator MM5 */</span>
<a name="l06853"></a>06853                                 movq mm2, [esi]         <span class="comment">/* load 8 bytes from Src */</span>
<a name="l06854"></a>06854                         movq mm3, mm2           <span class="comment">/* save MM2 in MM3 */</span>
<a name="l06855"></a>06855                                 sub esi, 2      <span class="comment">/* move ESI pointer back 2 bytes left */</span>
<a name="l06856"></a>06856                                 punpcklbw mm2, mm0      <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l06857"></a>06857                                 punpckhbw mm3, mm0      <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l06858"></a>06858                                 paddw mm6, mm2          <span class="comment">/* add 4 low  bytes to accumolator MM6 */</span>
<a name="l06859"></a>06859                                 paddw mm7, mm3          <span class="comment">/* add 4 high bytes to accumolator MM7 */</span>
<a name="l06860"></a>06860                                 paddw mm6, mm2          <span class="comment">/* add 4 low  bytes to accumolator MM6 */</span>
<a name="l06861"></a>06861                                 paddw mm7, mm3          <span class="comment">/* add 4 high bytes to accumolator MM7 */</span>
<a name="l06862"></a>06862                                 add esi, eax    <span class="comment">/* move to the next row of Src */</span>
<a name="l06863"></a>06863                                 movq mm2, [esi]         <span class="comment">/* load 8 bytes from Src */</span>
<a name="l06864"></a>06864                         movq mm3, mm2           <span class="comment">/* save MM2 in MM3 */</span>
<a name="l06865"></a>06865                                 add esi, 2      <span class="comment">/* move ESI pointer 2 bytes right */</span>
<a name="l06866"></a>06866                                 punpcklbw mm2, mm0      <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l06867"></a>06867                                 punpckhbw mm3, mm0      <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l06868"></a>06868                                 paddw mm4, mm2          <span class="comment">/* add 4 low  bytes to accumolator MM4 */</span>
<a name="l06869"></a>06869                                 paddw mm5, mm3          <span class="comment">/* add 4 high bytes to accumolator MM5 */</span>
<a name="l06870"></a>06870                                 movq mm2, [esi]         <span class="comment">/* load 8 bytes from Src */</span>
<a name="l06871"></a>06871                         movq mm3, mm2           <span class="comment">/* save MM2 in MM3 */</span>
<a name="l06872"></a>06872                                 sub esi, 2      <span class="comment">/* move ESI pointer back 2 bytes left */</span>
<a name="l06873"></a>06873                                 punpcklbw mm2, mm0      <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l06874"></a>06874                                 punpckhbw mm3, mm0      <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l06875"></a>06875                                 paddw mm6, mm2          <span class="comment">/* add 4 low  bytes to accumolator MM6 */</span>
<a name="l06876"></a>06876                                 paddw mm7, mm3          <span class="comment">/* add 4 high bytes to accumolator MM7 */</span>
<a name="l06877"></a>06877                                 <span class="comment">/* ---, */</span>
<a name="l06878"></a>06878                                 movq mm2, mm4           <span class="comment">/* copy MM4 into MM2 */</span>
<a name="l06879"></a>06879                                 psrlq mm4, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l06880"></a>06880                                 psubw mm4, mm2          <span class="comment">/* MM4 = MM4 - MM2 */</span>
<a name="l06881"></a>06881                                 movq mm3, mm6           <span class="comment">/* copy MM6 into MM3 */</span>
<a name="l06882"></a>06882                                 psrlq mm6, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l06883"></a>06883                                 psubw mm6, mm3          <span class="comment">/* MM6 = MM6 - MM3 */</span>
<a name="l06884"></a>06884                                 punpckldq mm4, mm6      <span class="comment">/* combine 2 words of MM6 and 2 words of MM4 */</span>
<a name="l06885"></a>06885                                 movq mm2, mm5           <span class="comment">/* copy MM6 into MM2 */</span>
<a name="l06886"></a>06886                                 psrlq mm5, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l06887"></a>06887                                 psubw mm5, mm2          <span class="comment">/* MM5 = MM5 - MM2 */</span>
<a name="l06888"></a>06888                                 movq mm3, mm7           <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l06889"></a>06889                                 psrlq mm7, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l06890"></a>06890                                 psubw mm7, mm3          <span class="comment">/* MM7 = MM7 - MM3 */</span>
<a name="l06891"></a>06891                                 punpckldq mm5, mm7      <span class="comment">/* combine 2 words of MM7 and 2 words of MM5 */</span>
<a name="l06892"></a>06892                                 <span class="comment">/* Take abs values of MM4 and MM5 */</span>
<a name="l06893"></a>06893                                 movq mm6, mm4           <span class="comment">/* copy MM4 into MM6 */</span>
<a name="l06894"></a>06894                                 movq mm7, mm5           <span class="comment">/* copy MM5 into MM7 */</span>
<a name="l06895"></a>06895                                 psraw mm6, 15           <span class="comment">/* fill MM6 words with word sign bit */</span>
<a name="l06896"></a>06896                                 psraw mm7, 15           <span class="comment">/* fill MM7 words with word sign bit */</span>
<a name="l06897"></a>06897                                 pxor mm4, mm6           <span class="comment">/* take 1&#39;s compliment of only neg words */</span>
<a name="l06898"></a>06898                                 pxor mm5, mm7           <span class="comment">/* take 1&#39;s compliment of only neg words */</span>
<a name="l06899"></a>06899                                 psubsw mm4, mm6         <span class="comment">/* add 1 to only neg words, W-(-1) or W-0 */</span>
<a name="l06900"></a>06900                                 psubsw mm5, mm7         <span class="comment">/* add 1 to only neg words, W-(-1) or W-0 */</span>
<a name="l06901"></a>06901                                 packuswb mm4, mm5       <span class="comment">/* combine and pack/saturate MM5 and MM4 */</span>
<a name="l06902"></a>06902                                 movq [edi], mm4         <span class="comment">/* store result in Dest */</span>
<a name="l06903"></a>06903                                 <span class="comment">/* ---, */</span>
<a name="l06904"></a>06904                                 sub esi, eax    <span class="comment">/* move to the current top row in Src */</span>
<a name="l06905"></a>06905                                 sub esi, eax
<a name="l06906"></a>06906                                 add esi, 8      <span class="comment">/* move Src  pointer to the next 8 pixels */</span>
<a name="l06907"></a>06907                                 add edi, 8      <span class="comment">/* move Dest pointer to the next 8 pixels */</span>
<a name="l06908"></a>06908                                 <span class="comment">/* ---, */</span>
<a name="l06909"></a>06909                                 dec              ecx            <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l06910"></a>06910                                 jnz            L10402           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l06911"></a>06911                                 mov esi, ebx    <span class="comment">/* restore most left current row Src  address */</span>
<a name="l06912"></a>06912                                 movd edi, mm1           <span class="comment">/* restore most left current row Dest address */</span>
<a name="l06913"></a>06913                                 add esi, eax    <span class="comment">/* move to the next row in Src */</span>
<a name="l06914"></a>06914                                 add edi, eax    <span class="comment">/* move to the next row in Dest */</span>
<a name="l06915"></a>06915                                 dec              edx            <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l06916"></a>06916                                 jnz            L10400           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l06917"></a>06917                                 <span class="comment">/* ---, */</span>
<a name="l06918"></a>06918                                 emms                            <span class="comment">/* exit MMX state */</span>
<a name="l06919"></a>06919                                 popa
<a name="l06920"></a>06920                 }
<a name="l06921"></a>06921 <span class="preprocessor">#else</span>
<a name="l06922"></a>06922 <span class="preprocessor"></span>                <span class="keyword">asm</span> <span class="keyword">volatile</span>
<a name="l06923"></a>06923                         (<span class="stringliteral">&quot;pusha              \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm0, %%mm0 \n\t&quot;</span>        <span class="comment">/* zero MM0 */</span>
<a name="l06924"></a>06924                         <span class="stringliteral">&quot;mov          %3, %%eax \n\t&quot;</span>   <span class="comment">/* load columns into EAX */</span>
<a name="l06925"></a>06925                         <span class="comment">/* --- */</span>
<a name="l06926"></a>06926                         <span class="stringliteral">&quot;mov          %1, %%esi \n\t&quot;</span>   <span class="comment">/* ESI = Src row 0 address */</span>
<a name="l06927"></a>06927                         <span class="stringliteral">&quot;mov          %0, %%edi \n\t&quot;</span>   <span class="comment">/* load Dest address to EDI */</span>
<a name="l06928"></a>06928                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span>   <span class="comment">/* EDI = EDI + columns */</span>
<a name="l06929"></a>06929                         <span class="stringliteral">&quot;inc              %%edi \n\t&quot;</span>   <span class="comment">/* 1 byte offset from the left edge */</span>
<a name="l06930"></a>06930                         <span class="stringliteral">&quot;mov          %2, %%edx \n\t&quot;</span>   <span class="comment">/* initialize ROWS counter */</span>
<a name="l06931"></a>06931                         <span class="stringliteral">&quot;sub          $2, %%edx \n\t&quot;</span>   <span class="comment">/* do not use first and last rows */</span>
<a name="l06932"></a>06932                         <span class="comment">/* --- */</span>
<a name="l06933"></a>06933                         <span class="stringliteral">&quot;.L10400:                \n\t&quot;</span> <span class="stringliteral">&quot;mov       %%eax, %%ecx \n\t&quot;</span>    <span class="comment">/* initialize COLUMS counter */</span>
<a name="l06934"></a>06934                         <span class="stringliteral">&quot;shr          $3, %%ecx \n\t&quot;</span>   <span class="comment">/* EBX/8 (MMX loads 8 bytes at a time) */</span>
<a name="l06935"></a>06935                         <span class="stringliteral">&quot;mov       %%esi, %%ebx \n\t&quot;</span>   <span class="comment">/* save ESI in EBX */</span>
<a name="l06936"></a>06936                         <span class="stringliteral">&quot;movd      %%edi, %%mm1 \n\t&quot;</span>   <span class="comment">/* save EDI in MM1 */</span>
<a name="l06937"></a>06937                         <span class="stringliteral">&quot;.align 16              \n\t&quot;</span>   <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l06938"></a>06938                         <span class="stringliteral">&quot;.L10402:               \n\t&quot;</span>
<a name="l06939"></a>06939                         <span class="comment">/* --- */</span>
<a name="l06940"></a>06940                         <span class="stringliteral">&quot;movq    (%%esi), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 8 bytes from Src */</span>
<a name="l06941"></a>06941                         <span class="stringliteral">&quot;movq      %%mm4, %%mm5 \n\t&quot;</span>   <span class="comment">/* save MM4 in MM5 */</span>
<a name="l06942"></a>06942                         <span class="stringliteral">&quot;add          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move ESI pointer 2 bytes right */</span>
<a name="l06943"></a>06943                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm4 \n\t&quot;</span>   <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l06944"></a>06944                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm5 \n\t&quot;</span>   <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l06945"></a>06945                         <span class="stringliteral">&quot;movq    (%%esi), %%mm6 \n\t&quot;</span>   <span class="comment">/* load 8 bytes from Src */</span>
<a name="l06946"></a>06946                         <span class="stringliteral">&quot;movq      %%mm6, %%mm7 \n\t&quot;</span>   <span class="comment">/* save MM6 in MM7 */</span>
<a name="l06947"></a>06947                         <span class="stringliteral">&quot;sub          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move ESI pointer back 2 bytes left */</span>
<a name="l06948"></a>06948                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm6 \n\t&quot;</span>   <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l06949"></a>06949                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm7 \n\t&quot;</span>   <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l06950"></a>06950                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row of Src */</span>
<a name="l06951"></a>06951                         <span class="stringliteral">&quot;movq    (%%esi), %%mm2 \n\t&quot;</span>   <span class="comment">/* load 8 bytes from Src */</span>
<a name="l06952"></a>06952                         <span class="stringliteral">&quot;movq      %%mm2, %%mm3 \n\t&quot;</span>   <span class="comment">/* save MM2 in MM3 */</span>
<a name="l06953"></a>06953                         <span class="stringliteral">&quot;add          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move ESI pointer 2 bytes right */</span>
<a name="l06954"></a>06954                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l06955"></a>06955                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm3 \n\t&quot;</span>   <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l06956"></a>06956                         <span class="stringliteral">&quot;paddw     %%mm2, %%mm4 \n\t&quot;</span>   <span class="comment">/* add 4 low  bytes to accumolator MM4 */</span>
<a name="l06957"></a>06957                         <span class="stringliteral">&quot;paddw     %%mm3, %%mm5 \n\t&quot;</span>   <span class="comment">/* add 4 high bytes to accumolator MM5 */</span>
<a name="l06958"></a>06958                         <span class="stringliteral">&quot;paddw     %%mm2, %%mm4 \n\t&quot;</span>   <span class="comment">/* add 4 low  bytes to accumolator MM4 */</span>
<a name="l06959"></a>06959                         <span class="stringliteral">&quot;paddw     %%mm3, %%mm5 \n\t&quot;</span>   <span class="comment">/* add 4 high bytes to accumolator MM5 */</span>
<a name="l06960"></a>06960                         <span class="stringliteral">&quot;movq    (%%esi), %%mm2 \n\t&quot;</span>   <span class="comment">/* load 8 bytes from Src */</span>
<a name="l06961"></a>06961                         <span class="stringliteral">&quot;movq      %%mm2, %%mm3 \n\t&quot;</span>   <span class="comment">/* save MM2 in MM3 */</span>
<a name="l06962"></a>06962                         <span class="stringliteral">&quot;sub          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move ESI pointer back 2 bytes left */</span>
<a name="l06963"></a>06963                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l06964"></a>06964                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm3 \n\t&quot;</span>   <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l06965"></a>06965                         <span class="stringliteral">&quot;paddw     %%mm2, %%mm6 \n\t&quot;</span>   <span class="comment">/* add 4 low  bytes to accumolator MM6 */</span>
<a name="l06966"></a>06966                         <span class="stringliteral">&quot;paddw     %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 4 high bytes to accumolator MM7 */</span>
<a name="l06967"></a>06967                         <span class="stringliteral">&quot;paddw     %%mm2, %%mm6 \n\t&quot;</span>   <span class="comment">/* add 4 low  bytes to accumolator MM6 */</span>
<a name="l06968"></a>06968                         <span class="stringliteral">&quot;paddw     %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 4 high bytes to accumolator MM7 */</span>
<a name="l06969"></a>06969                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row of Src */</span>
<a name="l06970"></a>06970                         <span class="stringliteral">&quot;movq    (%%esi), %%mm2 \n\t&quot;</span>   <span class="comment">/* load 8 bytes from Src */</span>
<a name="l06971"></a>06971                         <span class="stringliteral">&quot;movq      %%mm2, %%mm3 \n\t&quot;</span>   <span class="comment">/* save MM2 in MM3 */</span>
<a name="l06972"></a>06972                         <span class="stringliteral">&quot;add          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move ESI pointer 2 bytes right */</span>
<a name="l06973"></a>06973                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l06974"></a>06974                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm3 \n\t&quot;</span>   <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l06975"></a>06975                         <span class="stringliteral">&quot;paddw     %%mm2, %%mm4 \n\t&quot;</span>   <span class="comment">/* add 4 low  bytes to accumolator MM4 */</span>
<a name="l06976"></a>06976                         <span class="stringliteral">&quot;paddw     %%mm3, %%mm5 \n\t&quot;</span>   <span class="comment">/* add 4 high bytes to accumolator MM5 */</span>
<a name="l06977"></a>06977                         <span class="stringliteral">&quot;movq    (%%esi), %%mm2 \n\t&quot;</span>   <span class="comment">/* load 8 bytes from Src */</span>
<a name="l06978"></a>06978                         <span class="stringliteral">&quot;movq      %%mm2, %%mm3 \n\t&quot;</span>   <span class="comment">/* save MM2 in MM3 */</span>
<a name="l06979"></a>06979                         <span class="stringliteral">&quot;sub          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move ESI pointer back 2 bytes left */</span>
<a name="l06980"></a>06980                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l06981"></a>06981                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm3 \n\t&quot;</span>   <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l06982"></a>06982                         <span class="stringliteral">&quot;paddw     %%mm2, %%mm6 \n\t&quot;</span>   <span class="comment">/* add 4 low  bytes to accumolator MM6 */</span>
<a name="l06983"></a>06983                         <span class="stringliteral">&quot;paddw     %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 4 high bytes to accumolator MM7 */</span>
<a name="l06984"></a>06984                         <span class="comment">/* --- */</span>
<a name="l06985"></a>06985                         <span class="stringliteral">&quot;movq      %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM4 into MM2 */</span>
<a name="l06986"></a>06986                         <span class="stringliteral">&quot;psrlq       $32, %%mm4 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l06987"></a>06987                         <span class="stringliteral">&quot;psubw     %%mm2, %%mm4 \n\t&quot;</span>   <span class="comment">/* MM4 = MM4 - MM2 */</span>
<a name="l06988"></a>06988                         <span class="stringliteral">&quot;movq      %%mm6, %%mm3 \n\t&quot;</span>   <span class="comment">/* copy MM6 into MM3 */</span>
<a name="l06989"></a>06989                         <span class="stringliteral">&quot;psrlq       $32, %%mm6 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l06990"></a>06990                         <span class="stringliteral">&quot;psubw     %%mm3, %%mm6 \n\t&quot;</span>   <span class="comment">/* MM6 = MM6 - MM3 */</span>
<a name="l06991"></a>06991                         <span class="stringliteral">&quot;punpckldq %%mm6, %%mm4 \n\t&quot;</span>   <span class="comment">/* combine 2 words of MM6 and 2 words of MM4 */</span>
<a name="l06992"></a>06992                         <span class="stringliteral">&quot;movq      %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM6 into MM2 */</span>
<a name="l06993"></a>06993                         <span class="stringliteral">&quot;psrlq       $32, %%mm5 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l06994"></a>06994                         <span class="stringliteral">&quot;psubw     %%mm2, %%mm5 \n\t&quot;</span>   <span class="comment">/* MM5 = MM5 - MM2 */</span>
<a name="l06995"></a>06995                         <span class="stringliteral">&quot;movq      %%mm7, %%mm3 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l06996"></a>06996                         <span class="stringliteral">&quot;psrlq       $32, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l06997"></a>06997                         <span class="stringliteral">&quot;psubw     %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* MM7 = MM7 - MM3 */</span>
<a name="l06998"></a>06998                         <span class="stringliteral">&quot;punpckldq %%mm7, %%mm5 \n\t&quot;</span>   <span class="comment">/* combine 2 words of MM7 and 2 words of MM5 */</span>
<a name="l06999"></a>06999                         <span class="comment">/* Take abs values of MM4 and MM5 */</span>
<a name="l07000"></a>07000                         <span class="stringliteral">&quot;movq      %%mm4, %%mm6 \n\t&quot;</span>   <span class="comment">/* copy MM4 into MM6 */</span>
<a name="l07001"></a>07001                         <span class="stringliteral">&quot;movq      %%mm5, %%mm7 \n\t&quot;</span>   <span class="comment">/* copy MM5 into MM7 */</span>
<a name="l07002"></a>07002                         <span class="stringliteral">&quot;psraw       $15, %%mm6 \n\t&quot;</span>   <span class="comment">/* fill MM6 words with word sign bit */</span>
<a name="l07003"></a>07003                         <span class="stringliteral">&quot;psraw       $15, %%mm7 \n\t&quot;</span>   <span class="comment">/* fill MM7 words with word sign bit */</span>
<a name="l07004"></a>07004                         <span class="stringliteral">&quot;pxor      %%mm6, %%mm4 \n\t&quot;</span>   <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l07005"></a>07005                         <span class="stringliteral">&quot;pxor      %%mm7, %%mm5 \n\t&quot;</span>   <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l07006"></a>07006                         <span class="stringliteral">&quot;psubsw    %%mm6, %%mm4 \n\t&quot;</span>   <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l07007"></a>07007                         <span class="stringliteral">&quot;psubsw    %%mm7, %%mm5 \n\t&quot;</span>   <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l07008"></a>07008                         <span class="stringliteral">&quot;packuswb  %%mm5, %%mm4 \n\t&quot;</span>   <span class="comment">/* combine and pack/saturate MM5 and MM4 */</span>
<a name="l07009"></a>07009                         <span class="stringliteral">&quot;movq    %%mm4, (%%edi) \n\t&quot;</span>   <span class="comment">/* store result in Dest */</span>
<a name="l07010"></a>07010                         <span class="comment">/* --- */</span>
<a name="l07011"></a>07011                         <span class="stringliteral">&quot;sub       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move to the current top row in Src */</span>
<a name="l07012"></a>07012                         <span class="stringliteral">&quot;sub       %%eax, %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add $8,          %%esi \n\t&quot;</span>     <span class="comment">/* move Src  pointer to the next 8 pixels */</span>
<a name="l07013"></a>07013                         <span class="stringliteral">&quot;add $8,          %%edi \n\t&quot;</span>   <span class="comment">/* move Dest pointer to the next 8 pixels */</span>
<a name="l07014"></a>07014                         <span class="comment">/* --- */</span>
<a name="l07015"></a>07015                         <span class="stringliteral">&quot;dec              %%ecx \n\t&quot;</span>   <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l07016"></a>07016                         <span class="stringliteral">&quot;jnz            .L10402 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l07017"></a>07017                         <span class="stringliteral">&quot;mov       %%ebx, %%esi \n\t&quot;</span>   <span class="comment">/* restore most left current row Src  address */</span>
<a name="l07018"></a>07018                         <span class="stringliteral">&quot;movd      %%mm1, %%edi \n\t&quot;</span>   <span class="comment">/* restore most left current row Dest address */</span>
<a name="l07019"></a>07019                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row in Src */</span>
<a name="l07020"></a>07020                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span>   <span class="comment">/* move to the next row in Dest */</span>
<a name="l07021"></a>07021                         <span class="stringliteral">&quot;dec              %%edx \n\t&quot;</span>   <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l07022"></a>07022                         <span class="stringliteral">&quot;jnz            .L10400 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l07023"></a>07023                         <span class="comment">/* --- */</span>
<a name="l07024"></a>07024                         <span class="stringliteral">&quot;emms                   \n\t&quot;</span>   <span class="comment">/* exit MMX state */</span>
<a name="l07025"></a>07025                         <span class="stringliteral">&quot;popa                   \n\t&quot;</span>:<span class="stringliteral">&quot;=m&quot;</span> (Dest)       <span class="comment">/* %0 */</span>
<a name="l07026"></a>07026                         :<span class="stringliteral">&quot;m&quot;</span>(Src),              <span class="comment">/* %1 */</span>
<a name="l07027"></a>07027                         <span class="stringliteral">&quot;m&quot;</span>(rows),              <span class="comment">/* %2 */</span>
<a name="l07028"></a>07028                         <span class="stringliteral">&quot;m&quot;</span>(columns)            <span class="comment">/* %3 */</span>
<a name="l07029"></a>07029                         );
<a name="l07030"></a>07030 <span class="preprocessor">#endif</span>
<a name="l07031"></a>07031 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l07032"></a>07032 <span class="preprocessor"></span>                <span class="keywordflow">return</span> (0);
<a name="l07033"></a>07033         } <span class="keywordflow">else</span> {
<a name="l07034"></a>07034                 <span class="comment">/* No non-MMX implementation yet */</span>
<a name="l07035"></a>07035                 <span class="keywordflow">return</span> (-1);
<a name="l07036"></a>07036         }
<a name="l07037"></a>07037 }
<a name="l07038"></a>07038 
<a name="l07052"></a><a class="code" href="_s_d_l2__image_filter_8c.html#a0d21af83f0183fcd697324cffe3ab3d7">07052</a> <span class="keywordtype">int</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a0d21af83f0183fcd697324cffe3ab3d7" title="Filter using SobelXShiftRight: Dij = saturation255( ... )">SDL_imageFilterSobelXShiftRight</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Src, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *Dest, <span class="keywordtype">int</span> rows, <span class="keywordtype">int</span> columns,
<a name="l07053"></a>07053                                                                         <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> NRightShift)
<a name="l07054"></a>07054 {
<a name="l07055"></a>07055         <span class="comment">/* Validate input parameters */</span>
<a name="l07056"></a>07056         <span class="keywordflow">if</span> ((Src == NULL) || (Dest == NULL))
<a name="l07057"></a>07057                 <span class="keywordflow">return</span>(-1);
<a name="l07058"></a>07058         <span class="keywordflow">if</span> ((columns &lt; 8) || (rows &lt; 3) || (NRightShift &gt; 7))
<a name="l07059"></a>07059                 <span class="keywordflow">return</span> (-1);
<a name="l07060"></a>07060 
<a name="l07061"></a>07061         <span class="keywordflow">if</span> ((<a class="code" href="_s_d_l2__image_filter_8c.html#a798ce71024ee1a1d1b174fd60fe79917" title="MMX detection routine (with override flag).">SDL_imageFilterMMXdetect</a>())) {
<a name="l07062"></a>07062 <span class="comment">//#ifdef USE_MMX</span>
<a name="l07063"></a>07063 <span class="preprocessor">#if defined(USE_MMX) &amp;&amp; defined(i386)</span>
<a name="l07064"></a>07064 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l07065"></a>07065 <span class="preprocessor"></span>                __asm
<a name="l07066"></a>07066                 {
<a name="l07067"></a>07067                         pusha
<a name="l07068"></a>07068                                 pxor mm0, mm0           <span class="comment">/* zero MM0 */</span>
<a name="l07069"></a>07069                                 mov eax, columns        <span class="comment">/* load columns into EAX */</span>
<a name="l07070"></a>07070                                 xor ebx, ebx    <span class="comment">/* zero EBX */</span>
<a name="l07071"></a>07071                                 mov bl, NRightShift     <span class="comment">/* load NRightShift into BL */</span>
<a name="l07072"></a>07072                                 movd mm1, ebx           <span class="comment">/* copy NRightShift into MM1 */</span>
<a name="l07073"></a>07073                                 <span class="comment">/* ---, */</span>
<a name="l07074"></a>07074                                 mov esi, Src    <span class="comment">/* ESI = Src row 0 address */</span>
<a name="l07075"></a>07075                                 mov edi, Dest           <span class="comment">/* load Dest address to EDI */</span>
<a name="l07076"></a>07076                                 add edi, eax    <span class="comment">/* EDI = EDI + columns */</span>
<a name="l07077"></a>07077                                 inc              edi            <span class="comment">/* 1 byte offset from the left edge */</span>
<a name="l07078"></a>07078                                 <span class="comment">/* initialize ROWS counter */</span>
<a name="l07079"></a>07079                                 sub rows, 2     <span class="comment">/* do not use first and last rows */</span>
<a name="l07080"></a>07080                                 <span class="comment">/* ---, */</span>
<a name="l07081"></a>07081 L10410:
<a name="l07082"></a>07082                         mov ecx, eax    <span class="comment">/* initialize COLUMS counter */</span>
<a name="l07083"></a>07083                                 shr ecx, 3      <span class="comment">/* EBX/8 (MMX loads 8 bytes at a time) */</span>
<a name="l07084"></a>07084                                 mov ebx, esi    <span class="comment">/* save ESI in EBX */</span>
<a name="l07085"></a>07085                                 mov edx, edi    <span class="comment">/* save EDI in EDX */</span>
<a name="l07086"></a>07086                                 align 16                        <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l07087"></a>07087 L10412:
<a name="l07088"></a>07088                         <span class="comment">/* ---, */</span>
<a name="l07089"></a>07089                         movq mm4, [esi]         <span class="comment">/* load 8 bytes from Src */</span>
<a name="l07090"></a>07090                         movq mm5, mm4           <span class="comment">/* save MM4 in MM5 */</span>
<a name="l07091"></a>07091                                 add esi, 2      <span class="comment">/* move ESI pointer 2 bytes right */</span>
<a name="l07092"></a>07092                                 punpcklbw mm4, mm0      <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l07093"></a>07093                                 punpckhbw mm5, mm0      <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l07094"></a>07094                                 psrlw mm4, mm1          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07095"></a>07095                                 psrlw mm5, mm1          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07096"></a>07096                                 movq mm6, [esi]         <span class="comment">/* load 8 bytes from Src */</span>
<a name="l07097"></a>07097                         movq mm7, mm6           <span class="comment">/* save MM6 in MM7 */</span>
<a name="l07098"></a>07098                                 sub esi, 2      <span class="comment">/* move ESI pointer back 2 bytes left */</span>
<a name="l07099"></a>07099                                 punpcklbw mm6, mm0      <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l07100"></a>07100                                 punpckhbw mm7, mm0      <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l07101"></a>07101                                 psrlw mm6, mm1          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07102"></a>07102                                 psrlw mm7, mm1          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07103"></a>07103                                 add esi, eax    <span class="comment">/* move to the next row of Src */</span>
<a name="l07104"></a>07104                                 movq mm2, [esi]         <span class="comment">/* load 8 bytes from Src */</span>
<a name="l07105"></a>07105                         movq mm3, mm2           <span class="comment">/* save MM2 in MM3 */</span>
<a name="l07106"></a>07106                                 add esi, 2      <span class="comment">/* move ESI pointer 2 bytes right */</span>
<a name="l07107"></a>07107                                 punpcklbw mm2, mm0      <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l07108"></a>07108                                 punpckhbw mm3, mm0      <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l07109"></a>07109                                 psrlw mm2, mm1          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07110"></a>07110                                 psrlw mm3, mm1          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07111"></a>07111                                 paddw mm4, mm2          <span class="comment">/* add 4 low  bytes to accumolator MM4 */</span>
<a name="l07112"></a>07112                                 paddw mm5, mm3          <span class="comment">/* add 4 high bytes to accumolator MM5 */</span>
<a name="l07113"></a>07113                                 paddw mm4, mm2          <span class="comment">/* add 4 low  bytes to accumolator MM4 */</span>
<a name="l07114"></a>07114                                 paddw mm5, mm3          <span class="comment">/* add 4 high bytes to accumolator MM5 */</span>
<a name="l07115"></a>07115                                 movq mm2, [esi]         <span class="comment">/* load 8 bytes from Src */</span>
<a name="l07116"></a>07116                         movq mm3, mm2           <span class="comment">/* save MM2 in MM3 */</span>
<a name="l07117"></a>07117                                 sub esi, 2      <span class="comment">/* move ESI pointer back 2 bytes left */</span>
<a name="l07118"></a>07118                                 punpcklbw mm2, mm0      <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l07119"></a>07119                                 punpckhbw mm3, mm0      <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l07120"></a>07120                                 psrlw mm2, mm1          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07121"></a>07121                                 psrlw mm3, mm1          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07122"></a>07122                                 paddw mm6, mm2          <span class="comment">/* add 4 low  bytes to accumolator MM6 */</span>
<a name="l07123"></a>07123                                 paddw mm7, mm3          <span class="comment">/* add 4 high bytes to accumolator MM7 */</span>
<a name="l07124"></a>07124                                 paddw mm6, mm2          <span class="comment">/* add 4 low  bytes to accumolator MM6 */</span>
<a name="l07125"></a>07125                                 paddw mm7, mm3          <span class="comment">/* add 4 high bytes to accumolator MM7 */</span>
<a name="l07126"></a>07126                                 add esi, eax    <span class="comment">/* move to the next row of Src */</span>
<a name="l07127"></a>07127                                 movq mm2, [esi]         <span class="comment">/* load 8 bytes from Src */</span>
<a name="l07128"></a>07128                         movq mm3, mm2           <span class="comment">/* save MM2 in MM3 */</span>
<a name="l07129"></a>07129                                 add esi, 2      <span class="comment">/* move ESI pointer 2 bytes right */</span>
<a name="l07130"></a>07130                                 punpcklbw mm2, mm0      <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l07131"></a>07131                                 punpckhbw mm3, mm0      <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l07132"></a>07132                                 psrlw mm2, mm1          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07133"></a>07133                                 psrlw mm3, mm1          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07134"></a>07134                                 paddw mm4, mm2          <span class="comment">/* add 4 low  bytes to accumolator MM4 */</span>
<a name="l07135"></a>07135                                 paddw mm5, mm3          <span class="comment">/* add 4 high bytes to accumolator MM5 */</span>
<a name="l07136"></a>07136                                 movq mm2, [esi]         <span class="comment">/* load 8 bytes from Src */</span>
<a name="l07137"></a>07137                         movq mm3, mm2           <span class="comment">/* save MM2 in MM3 */</span>
<a name="l07138"></a>07138                                 sub esi, 2      <span class="comment">/* move ESI pointer back 2 bytes left */</span>
<a name="l07139"></a>07139                                 punpcklbw mm2, mm0      <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l07140"></a>07140                                 punpckhbw mm3, mm0      <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l07141"></a>07141                                 psrlw mm2, mm1          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07142"></a>07142                                 psrlw mm3, mm1          <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07143"></a>07143                                 paddw mm6, mm2          <span class="comment">/* add 4 low  bytes to accumolator MM6 */</span>
<a name="l07144"></a>07144                                 paddw mm7, mm3          <span class="comment">/* add 4 high bytes to accumolator MM7 */</span>
<a name="l07145"></a>07145                                 <span class="comment">/* ---, */</span>
<a name="l07146"></a>07146                                 movq mm2, mm4           <span class="comment">/* copy MM4 into MM2 */</span>
<a name="l07147"></a>07147                                 psrlq mm4, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l07148"></a>07148                                 psubw mm4, mm2          <span class="comment">/* MM4 = MM4 - MM2 */</span>
<a name="l07149"></a>07149                                 movq mm3, mm6           <span class="comment">/* copy MM6 into MM3 */</span>
<a name="l07150"></a>07150                                 psrlq mm6, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l07151"></a>07151                                 psubw mm6, mm3          <span class="comment">/* MM6 = MM6 - MM3 */</span>
<a name="l07152"></a>07152                                 punpckldq mm4, mm6      <span class="comment">/* combine 2 words of MM6 and 2 words of MM4 */</span>
<a name="l07153"></a>07153                                 movq mm2, mm5           <span class="comment">/* copy MM6 into MM2 */</span>
<a name="l07154"></a>07154                                 psrlq mm5, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l07155"></a>07155                                 psubw mm5, mm2          <span class="comment">/* MM5 = MM5 - MM2 */</span>
<a name="l07156"></a>07156                                 movq mm3, mm7           <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l07157"></a>07157                                 psrlq mm7, 32           <span class="comment">/* shift 2 left words to the right */</span>
<a name="l07158"></a>07158                                 psubw mm7, mm3          <span class="comment">/* MM7 = MM7 - MM3 */</span>
<a name="l07159"></a>07159                                 punpckldq mm5, mm7      <span class="comment">/* combine 2 words of MM7 and 2 words of MM5 */</span>
<a name="l07160"></a>07160                                 <span class="comment">/* Take abs values of MM4 and MM5 */</span>
<a name="l07161"></a>07161                                 movq mm6, mm4           <span class="comment">/* copy MM4 into MM6 */</span>
<a name="l07162"></a>07162                                 movq mm7, mm5           <span class="comment">/* copy MM5 into MM7 */</span>
<a name="l07163"></a>07163                                 psraw mm6, 15           <span class="comment">/* fill MM6 words with word sign bit */</span>
<a name="l07164"></a>07164                                 psraw mm7, 15           <span class="comment">/* fill MM7 words with word sign bit */</span>
<a name="l07165"></a>07165                                 pxor mm4, mm6           <span class="comment">/* take 1&#39;s compliment of only neg words */</span>
<a name="l07166"></a>07166                                 pxor mm5, mm7           <span class="comment">/* take 1&#39;s compliment of only neg words */</span>
<a name="l07167"></a>07167                                 psubsw mm4, mm6         <span class="comment">/* add 1 to only neg words, W-(-1) or W-0 */</span>
<a name="l07168"></a>07168                                 psubsw mm5, mm7         <span class="comment">/* add 1 to only neg words, W-(-1) or W-0 */</span>
<a name="l07169"></a>07169                                 packuswb mm4, mm5       <span class="comment">/* combine and pack/saturate MM5 and MM4 */</span>
<a name="l07170"></a>07170                                 movq [edi], mm4         <span class="comment">/* store result in Dest */</span>
<a name="l07171"></a>07171                                 <span class="comment">/* ---, */</span>
<a name="l07172"></a>07172                                 sub esi, eax    <span class="comment">/* move to the current top row in Src */</span>
<a name="l07173"></a>07173                                 sub esi, eax
<a name="l07174"></a>07174                                 add esi, 8      <span class="comment">/* move Src  pointer to the next 8 pixels */</span>
<a name="l07175"></a>07175                                 add edi, 8      <span class="comment">/* move Dest pointer to the next 8 pixels */</span>
<a name="l07176"></a>07176                                 <span class="comment">/* ---, */</span>
<a name="l07177"></a>07177                                 dec              ecx            <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l07178"></a>07178                                 jnz            L10412           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l07179"></a>07179                                 mov esi, ebx    <span class="comment">/* restore most left current row Src  address */</span>
<a name="l07180"></a>07180                                 mov edi, edx    <span class="comment">/* restore most left current row Dest address */</span>
<a name="l07181"></a>07181                                 add esi, eax    <span class="comment">/* move to the next row in Src */</span>
<a name="l07182"></a>07182                                 add edi, eax    <span class="comment">/* move to the next row in Dest */</span>
<a name="l07183"></a>07183                                 dec rows        <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l07184"></a>07184                                 jnz            L10410           <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l07185"></a>07185                                 <span class="comment">/* ---, */</span>
<a name="l07186"></a>07186                                 emms                            <span class="comment">/* exit MMX state */</span>
<a name="l07187"></a>07187                                 popa
<a name="l07188"></a>07188                 }
<a name="l07189"></a>07189 <span class="preprocessor">#else</span>
<a name="l07190"></a>07190 <span class="preprocessor"></span>                <span class="keyword">asm</span> <span class="keyword">volatile</span>
<a name="l07191"></a>07191                         (<span class="stringliteral">&quot;pusha              \n\t&quot;</span> <span class="stringliteral">&quot;pxor      %%mm0, %%mm0 \n\t&quot;</span>        <span class="comment">/* zero MM0 */</span>
<a name="l07192"></a>07192                         <span class="stringliteral">&quot;mov          %3, %%eax \n\t&quot;</span>   <span class="comment">/* load columns into EAX */</span>
<a name="l07193"></a>07193                         <span class="stringliteral">&quot;xor       %%ebx, %%ebx \n\t&quot;</span>   <span class="comment">/* zero EBX */</span>
<a name="l07194"></a>07194                         <span class="stringliteral">&quot;mov           %4, %%bl \n\t&quot;</span>   <span class="comment">/* load NRightShift into BL */</span>
<a name="l07195"></a>07195                         <span class="stringliteral">&quot;movd      %%ebx, %%mm1 \n\t&quot;</span>   <span class="comment">/* copy NRightShift into MM1 */</span>
<a name="l07196"></a>07196                         <span class="comment">/* --- */</span>
<a name="l07197"></a>07197                         <span class="stringliteral">&quot;mov          %1, %%esi \n\t&quot;</span>   <span class="comment">/* ESI = Src row 0 address */</span>
<a name="l07198"></a>07198                         <span class="stringliteral">&quot;mov          %0, %%edi \n\t&quot;</span>   <span class="comment">/* load Dest address to EDI */</span>
<a name="l07199"></a>07199                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span>   <span class="comment">/* EDI = EDI + columns */</span>
<a name="l07200"></a>07200                         <span class="stringliteral">&quot;inc              %%edi \n\t&quot;</span>   <span class="comment">/* 1 byte offset from the left edge */</span>
<a name="l07201"></a>07201                         <span class="comment">/* initialize ROWS counter */</span>
<a name="l07202"></a>07202                         <span class="stringliteral">&quot;subl            $2, %2 \n\t&quot;</span>   <span class="comment">/* do not use first and last rows */</span>
<a name="l07203"></a>07203                         <span class="comment">/* --- */</span>
<a name="l07204"></a>07204                         <span class="stringliteral">&quot;.L10410:                \n\t&quot;</span> <span class="stringliteral">&quot;mov       %%eax, %%ecx \n\t&quot;</span>    <span class="comment">/* initialize COLUMS counter */</span>
<a name="l07205"></a>07205                         <span class="stringliteral">&quot;shr          $3, %%ecx \n\t&quot;</span>   <span class="comment">/* EBX/8 (MMX loads 8 bytes at a time) */</span>
<a name="l07206"></a>07206                         <span class="stringliteral">&quot;mov       %%esi, %%ebx \n\t&quot;</span>   <span class="comment">/* save ESI in EBX */</span>
<a name="l07207"></a>07207                         <span class="stringliteral">&quot;mov       %%edi, %%edx \n\t&quot;</span>   <span class="comment">/* save EDI in EDX */</span>
<a name="l07208"></a>07208                         <span class="stringliteral">&quot;.align 16              \n\t&quot;</span>   <span class="comment">/* 16 byte alignment of the loop entry */</span>
<a name="l07209"></a>07209                         <span class="stringliteral">&quot;.L10412:               \n\t&quot;</span>
<a name="l07210"></a>07210                         <span class="comment">/* --- */</span>
<a name="l07211"></a>07211                         <span class="stringliteral">&quot;movq    (%%esi), %%mm4 \n\t&quot;</span>   <span class="comment">/* load 8 bytes from Src */</span>
<a name="l07212"></a>07212                         <span class="stringliteral">&quot;movq      %%mm4, %%mm5 \n\t&quot;</span>   <span class="comment">/* save MM4 in MM5 */</span>
<a name="l07213"></a>07213                         <span class="stringliteral">&quot;add          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move ESI pointer 2 bytes right */</span>
<a name="l07214"></a>07214                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm4 \n\t&quot;</span>   <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l07215"></a>07215                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm5 \n\t&quot;</span>   <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l07216"></a>07216                         <span class="stringliteral">&quot;psrlw     %%mm1, %%mm4 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07217"></a>07217                         <span class="stringliteral">&quot;psrlw     %%mm1, %%mm5 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07218"></a>07218                         <span class="stringliteral">&quot;movq    (%%esi), %%mm6 \n\t&quot;</span>   <span class="comment">/* load 8 bytes from Src */</span>
<a name="l07219"></a>07219                         <span class="stringliteral">&quot;movq      %%mm6, %%mm7 \n\t&quot;</span>   <span class="comment">/* save MM6 in MM7 */</span>
<a name="l07220"></a>07220                         <span class="stringliteral">&quot;sub          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move ESI pointer back 2 bytes left */</span>
<a name="l07221"></a>07221                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm6 \n\t&quot;</span>   <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l07222"></a>07222                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm7 \n\t&quot;</span>   <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l07223"></a>07223                         <span class="stringliteral">&quot;psrlw     %%mm1, %%mm6 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07224"></a>07224                         <span class="stringliteral">&quot;psrlw     %%mm1, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07225"></a>07225                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row of Src */</span>
<a name="l07226"></a>07226                         <span class="stringliteral">&quot;movq    (%%esi), %%mm2 \n\t&quot;</span>   <span class="comment">/* load 8 bytes from Src */</span>
<a name="l07227"></a>07227                         <span class="stringliteral">&quot;movq      %%mm2, %%mm3 \n\t&quot;</span>   <span class="comment">/* save MM2 in MM3 */</span>
<a name="l07228"></a>07228                         <span class="stringliteral">&quot;add          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move ESI pointer 2 bytes right */</span>
<a name="l07229"></a>07229                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l07230"></a>07230                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm3 \n\t&quot;</span>   <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l07231"></a>07231                         <span class="stringliteral">&quot;psrlw     %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07232"></a>07232                         <span class="stringliteral">&quot;psrlw     %%mm1, %%mm3 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07233"></a>07233                         <span class="stringliteral">&quot;paddw     %%mm2, %%mm4 \n\t&quot;</span>   <span class="comment">/* add 4 low  bytes to accumolator MM4 */</span>
<a name="l07234"></a>07234                         <span class="stringliteral">&quot;paddw     %%mm3, %%mm5 \n\t&quot;</span>   <span class="comment">/* add 4 high bytes to accumolator MM5 */</span>
<a name="l07235"></a>07235                         <span class="stringliteral">&quot;paddw     %%mm2, %%mm4 \n\t&quot;</span>   <span class="comment">/* add 4 low  bytes to accumolator MM4 */</span>
<a name="l07236"></a>07236                         <span class="stringliteral">&quot;paddw     %%mm3, %%mm5 \n\t&quot;</span>   <span class="comment">/* add 4 high bytes to accumolator MM5 */</span>
<a name="l07237"></a>07237                         <span class="stringliteral">&quot;movq    (%%esi), %%mm2 \n\t&quot;</span>   <span class="comment">/* load 8 bytes from Src */</span>
<a name="l07238"></a>07238                         <span class="stringliteral">&quot;movq      %%mm2, %%mm3 \n\t&quot;</span>   <span class="comment">/* save MM2 in MM3 */</span>
<a name="l07239"></a>07239                         <span class="stringliteral">&quot;sub          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move ESI pointer back 2 bytes left */</span>
<a name="l07240"></a>07240                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l07241"></a>07241                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm3 \n\t&quot;</span>   <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l07242"></a>07242                         <span class="stringliteral">&quot;psrlw     %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07243"></a>07243                         <span class="stringliteral">&quot;psrlw     %%mm1, %%mm3 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07244"></a>07244                         <span class="stringliteral">&quot;paddw     %%mm2, %%mm6 \n\t&quot;</span>   <span class="comment">/* add 4 low  bytes to accumolator MM6 */</span>
<a name="l07245"></a>07245                         <span class="stringliteral">&quot;paddw     %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 4 high bytes to accumolator MM7 */</span>
<a name="l07246"></a>07246                         <span class="stringliteral">&quot;paddw     %%mm2, %%mm6 \n\t&quot;</span>   <span class="comment">/* add 4 low  bytes to accumolator MM6 */</span>
<a name="l07247"></a>07247                         <span class="stringliteral">&quot;paddw     %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 4 high bytes to accumolator MM7 */</span>
<a name="l07248"></a>07248                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row of Src */</span>
<a name="l07249"></a>07249                         <span class="stringliteral">&quot;movq    (%%esi), %%mm2 \n\t&quot;</span>   <span class="comment">/* load 8 bytes from Src */</span>
<a name="l07250"></a>07250                         <span class="stringliteral">&quot;movq      %%mm2, %%mm3 \n\t&quot;</span>   <span class="comment">/* save MM2 in MM3 */</span>
<a name="l07251"></a>07251                         <span class="stringliteral">&quot;add          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move ESI pointer 2 bytes right */</span>
<a name="l07252"></a>07252                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l07253"></a>07253                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm3 \n\t&quot;</span>   <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l07254"></a>07254                         <span class="stringliteral">&quot;psrlw     %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07255"></a>07255                         <span class="stringliteral">&quot;psrlw     %%mm1, %%mm3 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07256"></a>07256                         <span class="stringliteral">&quot;paddw     %%mm2, %%mm4 \n\t&quot;</span>   <span class="comment">/* add 4 low  bytes to accumolator MM4 */</span>
<a name="l07257"></a>07257                         <span class="stringliteral">&quot;paddw     %%mm3, %%mm5 \n\t&quot;</span>   <span class="comment">/* add 4 high bytes to accumolator MM5 */</span>
<a name="l07258"></a>07258                         <span class="stringliteral">&quot;movq    (%%esi), %%mm2 \n\t&quot;</span>   <span class="comment">/* load 8 bytes from Src */</span>
<a name="l07259"></a>07259                         <span class="stringliteral">&quot;movq      %%mm2, %%mm3 \n\t&quot;</span>   <span class="comment">/* save MM2 in MM3 */</span>
<a name="l07260"></a>07260                         <span class="stringliteral">&quot;sub          $2, %%esi \n\t&quot;</span>   <span class="comment">/* move ESI pointer back 2 bytes left */</span>
<a name="l07261"></a>07261                         <span class="stringliteral">&quot;punpcklbw %%mm0, %%mm2 \n\t&quot;</span>   <span class="comment">/* unpack 4 low  bytes into words */</span>
<a name="l07262"></a>07262                         <span class="stringliteral">&quot;punpckhbw %%mm0, %%mm3 \n\t&quot;</span>   <span class="comment">/* unpack 4 high bytes into words */</span>
<a name="l07263"></a>07263                         <span class="stringliteral">&quot;psrlw     %%mm1, %%mm2 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07264"></a>07264                         <span class="stringliteral">&quot;psrlw     %%mm1, %%mm3 \n\t&quot;</span>   <span class="comment">/* shift right each pixel NshiftRight times */</span>
<a name="l07265"></a>07265                         <span class="stringliteral">&quot;paddw     %%mm2, %%mm6 \n\t&quot;</span>   <span class="comment">/* add 4 low  bytes to accumolator MM6 */</span>
<a name="l07266"></a>07266                         <span class="stringliteral">&quot;paddw     %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* add 4 high bytes to accumolator MM7 */</span>
<a name="l07267"></a>07267                         <span class="comment">/* --- */</span>
<a name="l07268"></a>07268                         <span class="stringliteral">&quot;movq      %%mm4, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM4 into MM2 */</span>
<a name="l07269"></a>07269                         <span class="stringliteral">&quot;psrlq       $32, %%mm4 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l07270"></a>07270                         <span class="stringliteral">&quot;psubw     %%mm2, %%mm4 \n\t&quot;</span>   <span class="comment">/* MM4 = MM4 - MM2 */</span>
<a name="l07271"></a>07271                         <span class="stringliteral">&quot;movq      %%mm6, %%mm3 \n\t&quot;</span>   <span class="comment">/* copy MM6 into MM3 */</span>
<a name="l07272"></a>07272                         <span class="stringliteral">&quot;psrlq       $32, %%mm6 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l07273"></a>07273                         <span class="stringliteral">&quot;psubw     %%mm3, %%mm6 \n\t&quot;</span>   <span class="comment">/* MM6 = MM6 - MM3 */</span>
<a name="l07274"></a>07274                         <span class="stringliteral">&quot;punpckldq %%mm6, %%mm4 \n\t&quot;</span>   <span class="comment">/* combine 2 words of MM6 and 2 words of MM4 */</span>
<a name="l07275"></a>07275                         <span class="stringliteral">&quot;movq      %%mm5, %%mm2 \n\t&quot;</span>   <span class="comment">/* copy MM6 into MM2 */</span>
<a name="l07276"></a>07276                         <span class="stringliteral">&quot;psrlq       $32, %%mm5 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l07277"></a>07277                         <span class="stringliteral">&quot;psubw     %%mm2, %%mm5 \n\t&quot;</span>   <span class="comment">/* MM5 = MM5 - MM2 */</span>
<a name="l07278"></a>07278                         <span class="stringliteral">&quot;movq      %%mm7, %%mm3 \n\t&quot;</span>   <span class="comment">/* copy MM7 into MM3 */</span>
<a name="l07279"></a>07279                         <span class="stringliteral">&quot;psrlq       $32, %%mm7 \n\t&quot;</span>   <span class="comment">/* shift 2 left words to the right */</span>
<a name="l07280"></a>07280                         <span class="stringliteral">&quot;psubw     %%mm3, %%mm7 \n\t&quot;</span>   <span class="comment">/* MM7 = MM7 - MM3 */</span>
<a name="l07281"></a>07281                         <span class="stringliteral">&quot;punpckldq %%mm7, %%mm5 \n\t&quot;</span>   <span class="comment">/* combine 2 words of MM7 and 2 words of MM5 */</span>
<a name="l07282"></a>07282                         <span class="comment">/* Take abs values of MM4 and MM5 */</span>
<a name="l07283"></a>07283                         <span class="stringliteral">&quot;movq      %%mm4, %%mm6 \n\t&quot;</span>   <span class="comment">/* copy MM4 into MM6 */</span>
<a name="l07284"></a>07284                         <span class="stringliteral">&quot;movq      %%mm5, %%mm7 \n\t&quot;</span>   <span class="comment">/* copy MM5 into MM7 */</span>
<a name="l07285"></a>07285                         <span class="stringliteral">&quot;psraw       $15, %%mm6 \n\t&quot;</span>   <span class="comment">/* fill MM6 words with word sign bit */</span>
<a name="l07286"></a>07286                         <span class="stringliteral">&quot;psraw       $15, %%mm7 \n\t&quot;</span>   <span class="comment">/* fill MM7 words with word sign bit */</span>
<a name="l07287"></a>07287                         <span class="stringliteral">&quot;pxor      %%mm6, %%mm4 \n\t&quot;</span>   <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l07288"></a>07288                         <span class="stringliteral">&quot;pxor      %%mm7, %%mm5 \n\t&quot;</span>   <span class="comment">/* take 1&#39;s compliment of only neg. words */</span>
<a name="l07289"></a>07289                         <span class="stringliteral">&quot;psubsw    %%mm6, %%mm4 \n\t&quot;</span>   <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l07290"></a>07290                         <span class="stringliteral">&quot;psubsw    %%mm7, %%mm5 \n\t&quot;</span>   <span class="comment">/* add 1 to only neg. words, W-(-1) or W-0 */</span>
<a name="l07291"></a>07291                         <span class="stringliteral">&quot;packuswb  %%mm5, %%mm4 \n\t&quot;</span>   <span class="comment">/* combine and pack/saturate MM5 and MM4 */</span>
<a name="l07292"></a>07292                         <span class="stringliteral">&quot;movq    %%mm4, (%%edi) \n\t&quot;</span>   <span class="comment">/* store result in Dest */</span>
<a name="l07293"></a>07293                         <span class="comment">/* --- */</span>
<a name="l07294"></a>07294                         <span class="stringliteral">&quot;sub       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move to the current top row in Src */</span>
<a name="l07295"></a>07295                         <span class="stringliteral">&quot;sub       %%eax, %%esi \n\t&quot;</span> <span class="stringliteral">&quot;add $8,          %%esi \n\t&quot;</span>     <span class="comment">/* move Src  pointer to the next 8 pixels */</span>
<a name="l07296"></a>07296                         <span class="stringliteral">&quot;add $8,          %%edi \n\t&quot;</span>   <span class="comment">/* move Dest pointer to the next 8 pixels */</span>
<a name="l07297"></a>07297                         <span class="comment">/* --- */</span>
<a name="l07298"></a>07298                         <span class="stringliteral">&quot;dec              %%ecx \n\t&quot;</span>   <span class="comment">/* decrease loop counter COLUMNS */</span>
<a name="l07299"></a>07299                         <span class="stringliteral">&quot;jnz            .L10412 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l07300"></a>07300                         <span class="stringliteral">&quot;mov       %%ebx, %%esi \n\t&quot;</span>   <span class="comment">/* restore most left current row Src  address */</span>
<a name="l07301"></a>07301                         <span class="stringliteral">&quot;mov       %%edx, %%edi \n\t&quot;</span>   <span class="comment">/* restore most left current row Dest address */</span>
<a name="l07302"></a>07302                         <span class="stringliteral">&quot;add       %%eax, %%esi \n\t&quot;</span>   <span class="comment">/* move to the next row in Src */</span>
<a name="l07303"></a>07303                         <span class="stringliteral">&quot;add       %%eax, %%edi \n\t&quot;</span>   <span class="comment">/* move to the next row in Dest */</span>
<a name="l07304"></a>07304                         <span class="stringliteral">&quot;decl                %2 \n\t&quot;</span>   <span class="comment">/* decrease loop counter ROWS */</span>
<a name="l07305"></a>07305                         <span class="stringliteral">&quot;jnz            .L10410 \n\t&quot;</span>   <span class="comment">/* check loop termination, proceed if required */</span>
<a name="l07306"></a>07306                         <span class="comment">/* --- */</span>
<a name="l07307"></a>07307                         <span class="stringliteral">&quot;emms                   \n\t&quot;</span>   <span class="comment">/* exit MMX state */</span>
<a name="l07308"></a>07308                         <span class="stringliteral">&quot;popa                   \n\t&quot;</span>:<span class="stringliteral">&quot;=m&quot;</span> (Dest)       <span class="comment">/* %0 */</span>
<a name="l07309"></a>07309                         :<span class="stringliteral">&quot;m&quot;</span>(Src),              <span class="comment">/* %1 */</span>
<a name="l07310"></a>07310                         <span class="stringliteral">&quot;m&quot;</span>(rows),              <span class="comment">/* %2 */</span>
<a name="l07311"></a>07311                         <span class="stringliteral">&quot;m&quot;</span>(columns),           <span class="comment">/* %3 */</span>
<a name="l07312"></a>07312                         <span class="stringliteral">&quot;m&quot;</span>(NRightShift)        <span class="comment">/* %4 */</span>
<a name="l07313"></a>07313                         );
<a name="l07314"></a>07314 <span class="preprocessor">#endif</span>
<a name="l07315"></a>07315 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l07316"></a>07316 <span class="preprocessor"></span>                <span class="keywordflow">return</span> (0);
<a name="l07317"></a>07317         } <span class="keywordflow">else</span> {
<a name="l07318"></a>07318                 <span class="comment">/* No non-MMX implementation yet */</span>
<a name="l07319"></a>07319                 <span class="keywordflow">return</span> (-1);
<a name="l07320"></a>07320         }
<a name="l07321"></a>07321 }
<a name="l07322"></a>07322 
<a name="l07326"></a><a class="code" href="_s_d_l2__image_filter_8c.html#afbfcc8c03e3d791ac74c955d14a135e4">07326</a> <span class="keywordtype">void</span> <a class="code" href="_s_d_l2__image_filter_8c.html#afbfcc8c03e3d791ac74c955d14a135e4" title="Align stack to 32 byte boundary,.">SDL_imageFilterAlignStack</a>(<span class="keywordtype">void</span>)
<a name="l07327"></a>07327 {
<a name="l07328"></a>07328 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l07329"></a>07329 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l07330"></a>07330 <span class="preprocessor"></span>        __asm
<a name="l07331"></a>07331         {                               <span class="comment">/* --- stack alignment --- */</span>
<a name="l07332"></a>07332                 mov ebx, esp    <span class="comment">/* load ESP into EBX */</span>
<a name="l07333"></a>07333                         sub ebx, 4      <span class="comment">/* reserve space on stack for old value of ESP */</span>
<a name="l07334"></a>07334                         and ebx, -32    <span class="comment">/* align EBX along a 32 byte boundary */</span>
<a name="l07335"></a>07335                         mov [ebx], esp          <span class="comment">/* save old value of ESP in stack, behind the bndry */</span>
<a name="l07336"></a>07336                         mov esp, ebx    <span class="comment">/* align ESP along a 32 byte boundary */</span>
<a name="l07337"></a>07337         }
<a name="l07338"></a>07338 <span class="preprocessor">#else</span>
<a name="l07339"></a>07339 <span class="preprocessor"></span>        <span class="keyword">asm</span> <span class="keyword">volatile</span>
<a name="l07340"></a>07340                 (                               <span class="comment">/* --- stack alignment --- */</span>
<a name="l07341"></a>07341                 <span class="stringliteral">&quot;mov       %%esp, %%ebx \n\t&quot;</span>   <span class="comment">/* load ESP into EBX */</span>
<a name="l07342"></a>07342                 <span class="stringliteral">&quot;sub          $4, %%ebx \n\t&quot;</span>   <span class="comment">/* reserve space on stack for old value of ESP */</span>
<a name="l07343"></a>07343                 <span class="stringliteral">&quot;and        $-32, %%ebx \n\t&quot;</span>   <span class="comment">/* align EBX along a 32 byte boundary */</span>
<a name="l07344"></a>07344                 <span class="stringliteral">&quot;mov     %%esp, (%%ebx) \n\t&quot;</span>   <span class="comment">/* save old value of ESP in stack, behind the bndry */</span>
<a name="l07345"></a>07345                 <span class="stringliteral">&quot;mov       %%ebx, %%esp \n\t&quot;</span>   <span class="comment">/* align ESP along a 32 byte boundary */</span>
<a name="l07346"></a>07346                 ::);
<a name="l07347"></a>07347 <span class="preprocessor">#endif</span>
<a name="l07348"></a>07348 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l07349"></a>07349 <span class="preprocessor"></span>}
<a name="l07350"></a>07350 
<a name="l07354"></a><a class="code" href="_s_d_l2__image_filter_8c.html#a3147eb5ddd4965d65702f0e533b42974">07354</a> <span class="keywordtype">void</span> <a class="code" href="_s_d_l2__image_filter_8c.html#a3147eb5ddd4965d65702f0e533b42974" title="Restore previously aligned stack.">SDL_imageFilterRestoreStack</a>(<span class="keywordtype">void</span>)
<a name="l07355"></a>07355 {
<a name="l07356"></a>07356 <span class="preprocessor">#ifdef USE_MMX</span>
<a name="l07357"></a>07357 <span class="preprocessor"></span><span class="preprocessor">#if !defined(GCC__)</span>
<a name="l07358"></a>07358 <span class="preprocessor"></span>        __asm
<a name="l07359"></a>07359         {                               <span class="comment">/* --- restoring old stack --- */</span>
<a name="l07360"></a>07360                 mov ebx, [esp]          <span class="comment">/* load old value of ESP */</span>
<a name="l07361"></a>07361                 mov esp, ebx    <span class="comment">/* restore old value of ESP */</span>
<a name="l07362"></a>07362         }
<a name="l07363"></a>07363 <span class="preprocessor">#else</span>
<a name="l07364"></a>07364 <span class="preprocessor"></span>        <span class="keyword">asm</span> <span class="keyword">volatile</span>
<a name="l07365"></a>07365                 (                               <span class="comment">/* --- restoring old stack --- */</span>
<a name="l07366"></a>07366                 <span class="stringliteral">&quot;mov     (%%esp), %%ebx \n\t&quot;</span>   <span class="comment">/* load old value of ESP */</span>
<a name="l07367"></a>07367                 <span class="stringliteral">&quot;mov       %%ebx, %%esp \n\t&quot;</span>   <span class="comment">/* restore old value of ESP */</span>
<a name="l07368"></a>07368                 ::);
<a name="l07369"></a>07369 <span class="preprocessor">#endif</span>
<a name="l07370"></a>07370 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l07371"></a>07371 <span class="preprocessor"></span>}
</pre></div></div><!-- contents -->


<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.0
</small></address>

</body>
</html>
